20 #include <basic/Tracer.hh>
23 #include <utility/exit.hh>
24 #include <utility/PyAssert.hh>
27 #include <boost/functional/hash.hpp>
30 #include <ObjexxFCL/format.hh>
31 #include <ObjexxFCL/string.functions.hh>
41 using namespace ObjexxFCL;
42 using namespace ObjexxFCL::fmt;
44 static basic::Tracer
TR(
"core.kinematics.FoldTree");
47 namespace kinematics {
50 FoldTree::~FoldTree() {}
70 edge_a != a_end; ++edge_a, ++edge_b ) {
71 if ( *edge_a != *edge_b )
return false;
89 using std::stringstream;
104 FoldTree::delete_self_edges()
106 if ( edge_list_.size() <= 1 )
return;
110 for (
iterator it = edge_list_.begin(), ite = edge_list_.end(); it != ite; ++it ) {
111 if ( it->start() == it->stop() ) delete_me.push_back( *it );
114 if ( !delete_me.empty() ) {
115 for (
Size i=1; i<= delete_me.size(); ++i ) {
116 delete_edge( delete_me[i] );
128 FoldTree::delete_seqpos(
int const seqpos )
130 PyAssert( (seqpos>0) && (seqpos<=nres()),
"FoldTree::delete_seqpos( int const seqpos ): input variable seqpos has a meaningless value");
131 if ( is_jump_point( seqpos ) || is_root( seqpos ) ) {
132 delete_jump_seqpos( seqpos );
134 delete_seqpos_simple( seqpos );
141 FoldTree::delete_jump_and_intervening_cutpoint(
int const jump_number )
143 delete_jump_and_intervening_cutpoint( jump_point(1,jump_number), jump_point(2,jump_number) );
149 FoldTree::delete_jump_and_intervening_cutpoint(
int jump_begin,
int jump_end )
151 PyAssert( (jump_begin>0) && (jump_begin<=num_jump()),
"FoldTree::delete_jump_and_intervening_cutpoint( int jump_begin , int jump_end ): input variable jump_begin has a meaningless value");
152 PyAssert( (jump_end>0) && (jump_end<=num_jump()),
"FoldTree::delete_jump_and_intervening_cutpoint( int jump_begin , int jump_end ): input variable jump_end has a meaningless value");
154 assert( is_jump_point( jump_begin ) && is_jump_point( jump_end ) );
156 if ( jump_begin > jump_end ) {
157 int tmp( jump_begin );
158 jump_begin = jump_end;
162 Size const old_num_jump( num_jump() );
163 Size const old_root( root() );
166 for (
Size i=1; i<= old_num_jump; ++i ) {
167 if ( jump_point(1,i) == jump_begin && jump_point(2,i) == jump_end ) jump_number = i;
169 assert( jump_number );
173 for (
int i=jump_begin; i<= jump_end-1; ++i ) {
174 if ( is_cutpoint( i ) ) {
175 if ( cut ) utility_exit_with_message(
"multiple cutpoints between jump positions!" );
181 add_edge( cut, cut+1, Edge::PEPTIDE );
182 delete_unordered_edge( jump_begin, jump_end, jump_number );
184 if ( jump_number < old_num_jump ) {
185 TR <<
"delete_jump_and_intervening_cutpoint: renumbering the remaining jumps!" << std::endl;
187 if ( it->is_jump() && (
Size)(it->label()) > jump_number ) it->label() = it->label() - 1;
191 delete_extra_vertices();
193 assert( check_fold_tree() );
200 FoldTree::slide_cutpoint(
Size const current_cut,
Size const target_cut )
202 assert( is_cutpoint( current_cut ) && !is_cutpoint( target_cut ) );
203 PyAssert( (is_cutpoint( current_cut )) && (!is_cutpoint( target_cut )),
"FoldTree::slide_cutpoint( Size const current_cut , Size const target_cut ): input variable current_cut or target_cut has a meaningless value");
204 Size const current_root( root() );
206 TR.Trace <<
"slide_cutpoint: current= "<< current_cut <<
" target= " << target_cut <<
' ' << *
this;
209 add_edge( current_cut, current_cut+1, Edge::PEPTIDE );
210 delete_unordered_edge( target_cut, target_cut+1, Edge::PEPTIDE );
211 reorder( current_root );
212 delete_extra_vertices();
214 assert( check_fold_tree() );
215 TR.Trace <<
"slide_cutpoint: final tree= " << *
this;
220 FoldTree::slide_jump(
Size const jump_number,
Size const new_res1,
Size const new_res2 )
222 TR.Debug <<
"slide_jump: starting tree= " << *
this;
223 Edge const old_jump_edge( jump_edge( jump_number ) );
225 Size const pos1( std::min( new_res1, new_res2 ) );
226 Size const pos2( std::max( new_res1, new_res2 ) );
231 if( it->label() != Edge::PEPTIDE )
continue;
232 if( (start <= pos1 && stop >= pos1) || (stop <= pos1 && start >= pos1) ) {
234 new_edges.push_back(
Edge(
start, pos1, Edge::PEPTIDE ) );
235 new_edges.push_back(
Edge( pos1,
stop, Edge::PEPTIDE ) );
236 remove_edges.push_back( *it );
238 if( (start <= pos2 && stop >= pos2) || (stop <= pos2 && start >= pos2) ) {
240 new_edges.push_back(
Edge(
start, pos2, Edge::PEPTIDE ) );
241 new_edges.push_back(
Edge( pos2,
stop, Edge::PEPTIDE ) );
242 remove_edges.push_back( *it );
252 Edge const new_jump_edge( pos1, pos2, jump_number );
253 delete_edge( old_jump_edge );
254 add_edge( new_jump_edge );
255 delete_extra_vertices();
257 TR.Debug <<
"slide_jump: final tree= " << *
this;
272 FoldTree::delete_jump_seqpos(
int const seqpos )
275 TR.Trace <<
"delete_jump_seqpos: " << seqpos <<
' ' << *
this << std::endl;
277 Size const old_nres( nres() );
278 assert( is_jump_point( seqpos ) || is_root( seqpos ) );
279 PyAssert( ( is_jump_point( seqpos )) || ( is_root( seqpos ) ),
"FoldTree::delete_jump_seqpos( int const seqpos): input variable seqpos has a meaningless value");
289 if ( it->stop() == seqpos ) incoming_edge = *it;
290 else if ( it->start() == seqpos ) {
291 outgoing_edges.push_back( *it );
292 if ( it->is_polymer() ) {
293 outgoing_polymer_edges.push_back( *it );
298 bool const is_root_rsd( is_root( seqpos ) );
299 assert( is_root_rsd == !incoming_edge.
valid() );
300 bool const is_polymer_rsd( ( !is_root_rsd && incoming_edge.
is_polymer() ) || !outgoing_polymer_edges.empty());
302 Size new_seqpos( 0 ), deleted_jump_number( 0 );
303 if ( is_polymer_rsd ) {
304 if ( !is_root_rsd && incoming_edge.
is_polymer() ) {
306 assert( incoming_edge.
stop() == seqpos );
310 Edge const & e( outgoing_polymer_edges.front() );
311 new_seqpos = seqpos + e.polymer_direction();
316 new_seqpos = begin()->stop();
317 if ( begin()->is_jump() ) deleted_jump_number = begin()->label();
320 new_seqpos = incoming_edge.
start();
321 if ( incoming_edge.
is_jump() ) deleted_jump_number = incoming_edge.
label();
324 assert( new_seqpos );
327 Size const old_num_jump( num_jump() );
328 if ( deleted_jump_number && deleted_jump_number != old_num_jump ) {
330 TR.Info <<
"delete_jump_seqpos: deleting jump " << deleted_jump_number << std::endl;
331 TR.Info <<
"delete_jump_seqpos: renumbering jump " << old_num_jump <<
" to " << deleted_jump_number << std::endl;
332 jump_edge( old_num_jump ).label() = deleted_jump_number;
333 jump_edge( deleted_jump_number ).label() = old_num_jump;
338 for (
iterator it = begin(), ite =
end(); it != ite; ++it ) {
339 if ( it->stop() == seqpos ) it->stop() = new_seqpos;
340 else if ( it->start() == seqpos ) it->start() = new_seqpos;
354 if ( edge_list_.size() == 1 && begin()->is_jump() &&
355 begin()->start() == begin()->stop() ) {
357 edge_list_.push_back(
Edge( 1, 1, Edge::PEPTIDE ) );
361 assert( check_fold_tree() );
363 TR.Trace <<
"delete_jump_seqpos: after " << seqpos <<
' ' << new_seqpos << *
this << std::endl;
368 FoldTree::get_jump_that_builds_residue(
int const seqpos )
const
371 Edge const & edge( get_residue_edge( seqpos ) );
372 if ( !edge.
is_jump() ) utility_exit_with_message(
"get_jump_that_builds_residue: not build by a jump!" );
381 FoldTree::delete_seqpos_simple(
int const seqpos )
383 TR.Trace <<
"delete_seqpos_simple: before " << seqpos <<
' ' << *
this << std::endl;
384 assert( !is_jump_point( seqpos ) && !is_root( seqpos ) );
386 Size const old_nres( nres() );
393 for (
iterator it = begin(), ite =
end(); it != ite; ++it ) {
394 assert( it->start() != seqpos );
395 if ( it->stop() == seqpos ) {
396 assert( it->is_polymer() );
397 it->stop() = it->stop() - it->polymer_direction();
413 assert( check_fold_tree() );
415 TR.Trace <<
"delete_seqpos_simple: after " << seqpos <<
' ' << *
this << std::endl;
425 it->start() = old2new[ it->start() ];
426 it->stop () = old2new[ it->stop () ];
449 FoldTree::insert_polymer_residue(
451 bool const join_lower,
452 bool const join_upper
455 int const old_size( nres() );
457 for (
int i=1; i<= old_size; ++i ) {
458 if ( i<seqpos ) old2new[i] = i;
459 else old2new[i] = i+1;
464 bool const special_case( is_cutpoint( seqpos -1 ) );
469 bool const seqpos_minus_1_is_vertex( seqpos > 1 && (is_jump_point( seqpos-1 ) || is_root(seqpos-1)));
470 bool const seqpos_is_vertex ( seqpos <= old_size && (is_jump_point( seqpos ) || is_root(seqpos)));
471 bool add_edge_lower( special_case && join_lower && seqpos_minus_1_is_vertex );
472 bool add_edge_upper( special_case && join_upper && seqpos_is_vertex );
474 for (
iterator it = edge_list_.begin(), ite = edge_list_.end(); it != ite; ++it ) {
475 it->start() = old2new[ it->start() ];
477 if ( special_case ) {
478 if ( join_lower && it->is_polymer() && it->stop() == seqpos - 1 && !seqpos_minus_1_is_vertex ) {
480 assert( !add_edge_lower );
483 if ( join_upper && it->is_polymer() && it->stop() == seqpos && !seqpos_is_vertex ) {
485 assert( !add_edge_upper );
490 it->stop () = old2new[ it->stop () ];
495 if ( add_edge_lower ) {
496 add_edge( seqpos-1, seqpos, Edge::PEPTIDE );
497 }
else if ( add_edge_upper ) {
498 add_edge( seqpos+1, seqpos, Edge::PEPTIDE );
501 assert( join_lower == !is_cutpoint( seqpos-1 ) && join_upper == !is_cutpoint( seqpos ) );
515 FoldTree::insert_residue_by_jump(
522 assert( is_cutpoint( seqpos - 1 ) );
523 int const old_size( nres() );
524 int const new_jump_number( num_jump() + 1 );
527 for (
int i=1; i<= old_size; ++i ) {
528 if ( i<seqpos ) old2new[i] = i;
529 else old2new[i] = i+1;
531 anchor_pos = old2new[ anchor_pos ];
533 for (
iterator it = edge_list_.begin(), ite = edge_list_.end(); it != ite; ++it ) {
534 it->start() = old2new[ it->start() ];
535 it->stop () = old2new[ it->stop () ];
538 add_edge( anchor_pos, seqpos, new_jump_number );
539 assert( check_fold_tree() );
541 if ( anchor_atom.size() ) {
542 assert( root_atom.size() );
543 set_jump_atoms( new_jump_number, anchor_atom, root_atom );
555 FoldTree::insert_fold_tree_by_jump(
557 int const insert_seqpos,
558 int const insert_jumppos,
559 int const anchor_pos,
560 int anchor_jump_number,
566 if ( !is_cutpoint( anchor_pos -1 ) && !is_cutpoint( anchor_pos ) ) {
567 TR.Warning <<
"insert_fold_tree_by_jump: anchor_pos is not a vertex of the tree!! anchor_pos= " << anchor_pos <<
569 TR.Warning <<
"*this= " << *
this <<
"Adding anchor_pos as a new vertex!" << std::endl;
573 int const old_nres( nres() );
574 int const old_njump( num_jump() );
575 int const insert_nres( subtree.
nres() );
576 int const insert_njump( subtree.
num_jump() );
577 int const new_njump( old_njump + insert_njump + 1 );
578 if ( !anchor_jump_number ) anchor_jump_number = new_njump;
580 TR.Trace <<
"insert_fold_tree_by_jump: insert_seqpos= " << insert_seqpos <<
" insert_jumppos= " << insert_jumppos <<
581 " anchor_pos= " << anchor_pos <<
" anchor_jump_number= " << anchor_jump_number <<
582 " old_nres= " << old_nres <<
" old_njump= " << old_njump <<
583 " insert_nres= " << insert_nres <<
" insert_njump= " << insert_njump << std::endl;
585 TR.Trace <<
"insert_fold_tree_by_jump: old_fold_tree: " << *
this;
586 TR.Trace <<
"insert_fold_tree_by_jump: subtree: " << subtree;
590 for (
int i=1; i<= old_nres; ++i ) {
591 if ( i < insert_seqpos ) old2new_res[ i ] = i;
592 else old2new_res[ i ] = i+insert_nres;
594 if ( anchor_jump_number >= insert_jumppos && anchor_jump_number < insert_jumppos + insert_njump ) {
595 utility_exit_with_message(
"anchor_jump_number cant fall within the range of inserted jumps!");
599 labeled[ anchor_jump_number ] =
true;
600 for (
int i= insert_jumppos; i< insert_jumppos+insert_njump; ++i ) labeled[i] =
true;
601 for (
int i=1; i<= old_njump; ++i ) {
602 int o2n( i < insert_jumppos ? i : i+insert_njump );
603 if ( o2n >= anchor_jump_number ) ++o2n;
604 if ( o2n >= insert_jumppos && o2n < insert_jumppos+insert_njump ) o2n = insert_jumppos + insert_njump;
605 assert( !labeled[ o2n ] );
606 labeled[ o2n ] =
true;
607 old2new_jump[ i ] = o2n;
611 for (
iterator it = edge_list_.begin(), ite = edge_list_.end(); it != ite; ++it ) {
612 it->start() = old2new_res[ it->start() ];
613 it->stop () = old2new_res[ it->stop () ];
614 if ( it->is_jump() ) {
615 it->label() = old2new_jump[ it->label() ];
620 int const root_pos( subtree.
root() + insert_seqpos - 1 );
621 edge_list_.push_back(
Edge( old2new_res[ anchor_pos ], root_pos, anchor_jump_number ) );
625 Edge new_edge( *it );
626 new_edge.
start() = new_edge.
start() + insert_seqpos-1;
627 new_edge.
stop () = new_edge.
stop () + insert_seqpos-1;
628 if ( new_edge.
is_jump() ) new_edge.
label() = new_edge.
label() + insert_jumppos-1;
630 edge_list_.push_back( new_edge );
635 if ( anchor_atom.size() ) {
636 assert( root_atom.size() );
637 set_jump_atoms( anchor_jump_number, anchor_atom, root_atom );
640 TR.Trace <<
"insert_fold_tree_by_jump: new fold_tree: " << *
this;
641 assert( check_fold_tree() );
651 FoldTree::append_residue(
652 bool const attach_by_jump,
653 int const jump_anchor_residue,
662 int const old_nres( nres() );
665 add_edge( old_nres, old_nres+1, Edge::PEPTIDE );
667 if ( old_nres == 1 ) delete_self_edges();
669 if ( attach_by_jump ) {
670 new_jump( jump_anchor_residue, old_nres + 1, old_nres );
671 if ( jump_upstream_atom.size() ) {
672 set_jump_atoms( num_jump(), jump_upstream_atom, jump_downstream_atom );
675 delete_extra_vertices();
681 FoldTree::append_residue_by_chemical_bond(
682 int const anchor_residue,
687 int const old_nres( nres() );
690 add_edge(
Edge( anchor_residue, old_nres+1, anchor_atom, root_atom ) );
694 assert( is_cutpoint( old_nres ) );
709 if ( start == stop && !( start == 1 && edge_list_.empty() ) )
return;
712 edge_list_.push_back(
Edge( start, stop, label ) );
725 if ( start == stop && !( start == 1 && edge_list_.empty() ) )
return;
727 edge_list_.push_back(
Edge( start, stop, start_atom, stop_atom ) );
735 Edge const & new_edge
739 edge_list_.push_back( new_edge );
750 if ( edge < edge_list_.begin() || edge >= edge_list_.end() ) {
751 TR.Fatal <<
"FoldTree::delete_edge(...) edge not contained in edge_list_." << std::endl;
754 edge_list_.erase( edge );
760 FoldTree::delete_edge(
Edge const & edge )
770 FoldTree::delete_unordered_edge(
779 it != it_end; ++it ) {
780 if ( it->label() == label &&
781 ( ( it->start() == start && it->stop() ==
stop ) ||
782 ( it->start() == stop && it->stop() ==
start ) ) ) {
783 edge_list_.erase( it );
789 TR.Fatal <<
"FoldTree::delete_unordered_edge(...) edge not in tree: " <<
790 ' ' << start <<
' ' << stop <<
' ' << label << std::endl;
803 FoldTree::delete_segment(
808 int const n2c(1),
c2n(-1);
810 TR.Info <<
"FoldTree::delete_segment: " << seg_begin <<
' ' <<
811 seg_end << std::endl;
813 int const size( seg_end - seg_begin + 1 );
815 FArray1D_int mapping( nres_, -1 );
816 for (
int i=1; i<= nres_; ++i ) {
817 if ( i < seg_begin ) {
819 }
else if ( i > seg_end ) {
820 mapping(i) = i -
size;
824 std::vector< Edge > new_edge_list_;
826 for (
iterator it = edge_list_.begin(), it_end = edge_list_.end();
827 it != it_end; ++it ) {
828 int pos1( mapping( it->start() ) );
829 int pos2( mapping( it->stop() ) );
830 int const dir( it->start() < it->stop() ?
n2c :
c2n );
831 if ( pos1 == -1 || pos2 == -1 ) assert( it->is_polymer() );
834 assert( (dir ==
n2c && it->start() == seg_begin && it->stop() > seg_end) ||
835 (dir == c2n && it->start() == seg_end && it->stop() < seg_begin) );
839 pos1 = seg_begin - 1;
841 }
else if ( pos2 == -1 ) {
842 assert( (dir == c2n && it->stop() == seg_begin && it->start() > seg_end) ||
843 (dir ==
n2c && it->stop() == seg_end && it->start() < seg_begin) );
847 pos2 = seg_begin - 1;
850 if ( pos1 != pos2 ) {
851 new_edge_list_.push_back(
Edge( pos1, pos2, it->label() ) );
858 edge_list_ = new_edge_list_;
868 FoldTree::update_edge_label(
877 it != it_end; ++it ) {
878 if ( it->label() == old_label &&
879 ( ( it->start() == start && it->stop() ==
stop ) ||
880 ( it->start() == stop && it->stop() ==
start ) ) ) {
881 it->label() = new_label;
887 TR.Fatal <<
"FoldTree::update_edge_label(...) edge not in tree: " <<
888 ' ' << start <<
' ' << stop <<
' ' << old_label << std::endl;
902 FoldTree::edge_label(
910 it != it_end; ++it ) {
911 if ( ( it->start() == start && it->stop() ==
stop ) ||
912 ( it->start() == stop && it->stop() ==
start ) ) {
919 TR.Fatal <<
"FoldTree::edge_label(...) edge not in tree: " <<
920 ' ' << start <<
' ' << stop <<
' ' << std::endl;
933 FoldTree::delete_extra_vertices()
942 int const _root( root() );
945 int kill_vertex( 0 );
946 for (
iterator it=edge_list_.begin(),it_end = edge_list_.end();
947 it != it_end && !kill_vertex; ++it ) {
955 if ( it->start() != _root &&
956 !is_jump_point_[ it->start() ] &&
957 !is_cutpoint_ ( it->start() ) &&
958 !is_cutpoint_ ( it->start()-1 ) ) kill_vertex = it->start();
959 if ( !is_jump_point_[ it->stop() ] &&
960 !is_cutpoint_ ( it->stop() ) &&
961 !is_cutpoint_ ( it->stop()-1 ) ) kill_vertex = it->stop();
962 if ( kill_vertex )
break;
964 if ( !kill_vertex )
break;
967 FArray1D_int bounds(2,0);
968 for (
iterator it=edge_list_.begin(),it_end = edge_list_.end();
969 it != it_end && nbounds<2; ++it ) {
970 if ( it->start() == kill_vertex ) {
972 bounds( nbounds ) = it->stop();
973 }
else if ( it->stop() == kill_vertex ) {
975 bounds( nbounds ) = it->start();
979 delete_unordered_edge( bounds(1), kill_vertex, Edge::PEPTIDE );
980 delete_unordered_edge( bounds(2), kill_vertex, Edge::PEPTIDE );
981 add_edge( bounds(1), bounds(2), Edge::PEPTIDE );
996 FoldTree::downstream_jump_residue(
int const jump_number )
const
999 assert( jump_number >= 1 && jump_number <= num_jump_ );
1001 it_end = edge_list_.end(); it != it_end; ++it ) {
1002 if ( it->label() == jump_number )
return it->stop();
1013 FoldTree::upstream_jump_residue(
int const jump_number )
const
1016 assert( jump_number >= 1 && jump_number <= num_jump_ );
1018 it_end = edge_list_.end(); it != it_end; ++it ) {
1019 if ( it->label() == jump_number )
return it->start();
1034 FoldTree::reorder(
int const start_residue )
1036 if ( new_topology ) update_nres();
1039 static FArray1D_bool linked;
1040 if ( nres_ !=
int( linked.size1() ) ) {
1041 linked.dimension( nres_ );
1049 linked( start_residue) =
true;
1051 bool new_member (
true);
1053 while ( new_member ) {
1056 it_end = edge_list_.end(); it != it_end; ++it) {
1057 Edge const& old_edge( *it );
1058 Edge edge( old_edge );
1059 if ( linked( edge.
start() ) && !linked( edge.
stop() ) ) {
1060 new_edge_list_.push_back( edge );
1061 linked( edge.
stop() ) =
true;
1063 }
else if ( linked( edge.
stop() ) && !linked( edge.
start() ) ) {
1069 new_edge_list_.push_back( edge );
1070 linked( edge.
stop() ) =
true;
1076 if ( new_edge_list_.size() != edge_list_.size() ) {
1077 TR.Error <<
"FoldTree::reorder( " << start_residue <<
" ) failed, new/old edge_list_ size mismatch" << std::endl;
1078 TR.Error << edge_list_.size() <<
' ' << new_edge_list_.size() << std::endl;
1095 edge_list_ = new_edge_list_;
1096 reassign_atoms_for_intra_residue_stubs();
1107 FoldTree::simple_tree(
int const nres_in )
1109 PyAssert( (nres_in>0),
"FoldTree::simple_tree( int const nres_in ): input variable nres_in has a meaningless value");
1110 new_topology =
true;
1112 add_edge(1, nres_in, Edge::PEPTIDE);
1119 FoldTree::is_simple_tree()
const {
1120 bool is_simple(
false );
1121 if ( edge_list_.size() == 1 ) {
1122 EdgeList::const_iterator e = begin();
1123 if ( e->start() == 1 && (
Size) e->stop() == nres() && e->is_polymer() )
1141 for (
iterator it= edge_list_.begin(), ite= edge_list_.end(); it != ite; ++it ) {
1142 if ( it->is_polymer() &&
1143 ( ( it->start() < v && it->stop () > v ) ||
1144 ( it->stop () < v && it->start() > v ) ) ) {
1145 int const start( std::min( it->start(), it->stop()) );
1146 int const stop ( std::max( it->start(), it->stop()) );
1148 if ( start < v ) add_edge( start, v, Edge::PEPTIDE );
1149 if ( stop > v ) add_edge( v, stop, Edge::PEPTIDE );
1153 new_topology =
true;
1162 int const jump_pos1,
1163 int const jump_pos2,
1164 int const new_cutpoint
1167 assert( !is_cutpoint( new_cutpoint ) );
1169 PyAssert( !is_cutpoint( new_cutpoint ),
"FoldTree::new_jump( int const new_cutpoint ): new_cutpoint is already a cutpoint!" );
1172 PyAssert( (jump_pos1>0) && (jump_pos1<=nres_),
"FoldTree::new_jump( int const jump_pos1 ): jump_pos1 is out of range!" );
1173 PyAssert( (jump_pos2>0) && (jump_pos2<=nres_),
"FoldTree::new_jump( int const jump_pos2 ): jump_pos2 is out of range!" );
1175 int const root( edge_list_.begin()->start() );
1176 int const new_jump_number( num_jump() + 1 );
1183 add_edge( jump_pos1, jump_pos2, new_jump_number );
1184 delete_unordered_edge( new_cutpoint, new_cutpoint+1, Edge::PEPTIDE );
1187 new_topology =
true;
1189 assert( is_cutpoint( new_cutpoint ) && is_jump_point( jump_pos1 ) && is_jump_point( jump_pos2 ) );
1192 return new_jump_number;
1198 FoldTree::new_chemical_bond(
1199 int const anchor_pos,
1203 int const new_cutpoint
1206 assert( !is_cutpoint( new_cutpoint ) );
1208 int const root( edge_list_.begin()->start() );
1215 Edge new_edge( anchor_pos, root_pos, anchor_atom, root_atom );
1217 add_edge( new_edge );
1218 delete_unordered_edge( new_cutpoint, new_cutpoint+1, Edge::PEPTIDE );
1221 new_topology =
true;
1223 assert( is_cutpoint( new_cutpoint ) && is_jump_point( anchor_pos ) && is_jump_point( root_pos ) );
1233 FoldTree::tree_from_jumps_and_cuts(
1235 int const num_jump_in,
1236 FArray2D_int
const & jump_point_in,
1237 FArray1D_int
const & cuts,
1244 new_topology =
true;
1246 if ( num_jump_in == 0 ) {
1249 add_edge( 1, nres_in, Edge::PEPTIDE );
1255 for (
int i = 1, iend = num_jump_in ; i <= iend ; ++i ) {
1256 TR.Debug <<
"Jump #" << i <<
" from " << jump_point_in( 1, i ) <<
1257 " to " << jump_point_in( 2, i ) << std::endl;
1263 typedef std::list< int > Int_list;
1264 Int_list vertex_list;
1266 FArray1D_bool is_cut( nres_in,
false );
1267 for (
int i = 1; i <= num_jump_in; ++i ) {
1268 for (
int j = 1; j <= 2; ++j ) {
1269 int const pos ( jump_point_in(j,i) );
1275 vertex_list.push_back( pos );
1277 assert( jump_point_in(1,i) < jump_point_in(2,i) );
1278 int const cut( cuts(i) );
1279 assert( cut >= 1 && cut < nres_in );
1280 is_cut( cut ) =
true;
1281 vertex_list.push_back( cut );
1282 vertex_list.push_back( cut+1 );
1287 vertex_list.unique();
1292 int const jump_stop( *( vertex_list.begin() ) );
1293 if ( jump_stop > 1 ) add_edge( 1, jump_stop, Edge::PEPTIDE );
1295 for ( Int_list::iterator it = vertex_list.begin(),
1296 it_end = vertex_list.end(); it != it_end; ++it ) {
1297 Int_list::iterator it_next (it);
1299 if ( it_next == it_end )
break;
1301 int const start ( *it );
1302 int const stop ( *it_next );
1303 assert( start >= 1 && start < stop && stop <= nres_in );
1304 if ( !is_cut(start) ) {
1305 add_edge( start, stop, Edge::PEPTIDE );
1307 assert( stop == start + 1 );
1312 Int_list::iterator last_jump_it = vertex_list.end();
1313 int const jump_start( *(--last_jump_it) );
1314 if ( jump_start < nres_in ) add_edge( jump_start, nres_in, Edge::PEPTIDE );
1321 for (
int i=1; i<= num_jump_in; ++i ) {
1322 add_edge( jump_point_in(1,i), jump_point_in(2,i), i );
1330 return check_fold_tree();
1352 bool FoldTree::random_tree_from_jump_points(
1354 int const num_jump_in,
1355 FArray2D_int
const & jump_point_in,
1356 FArray1D_float
const & cut_bias,
1358 bool const allow_jump_at_1_or_NRES )
1360 std::vector< int > obligate_cut_points;
1361 return random_tree_from_jump_points( nres_in, num_jump_in, jump_point_in, obligate_cut_points, cut_bias, root_in, allow_jump_at_1_or_NRES );
1366 FoldTree::random_tree_from_jump_points(
1368 int const num_jump_in,
1369 FArray2D_int
const & jump_point_in,
1370 std::vector< int >
const & obligate_cut_points,
1371 FArray1D_float
const & cut_bias,
1373 bool const allow_jump_at_1_or_NRES )
1377 new_topology =
true;
1379 if ( num_jump_in == 0 ) {
1382 add_edge( 1, nres_in, Edge::PEPTIDE );
1387 FArray1D_float cut_bias_sum( DRange(0,nres_in) );
1388 cut_bias_sum(0) = 0.0;
1389 for (
int i=1; i<= nres_in; ++i ) {
1390 cut_bias_sum(i) = cut_bias_sum( i-1 ) + cut_bias(i);
1396 typedef std::list< int > Int_list;
1399 for (
int i = 1; i <= num_jump_in; ++i ) {
1400 for (
int j = 1; j <= 2; ++j ) {
1401 if ( !allow_jump_at_1_or_NRES && (jump_point_in( j, i ) == 1 || jump_point_in( j, i ) == nres_in ) ) {
1402 TR.Warning <<
"attempt to create jump with residue 1 or NRES: not supported.. returning invalid tree" << std::endl;
1405 jump_list.push_back( jump_point_in(j,i) );
1418 int const jump_stop( *jump_list.begin() );
1419 if (jump_stop > 1) add_edge( 1, jump_stop, Edge::PEPTIDE );
1422 for ( Int_list::iterator it = jump_list.begin(),
1423 it_end = jump_list.end(); it != it_end; ++it ) {
1424 Int_list::iterator it_next (it);
1426 if ( it_next == it_end )
break;
1428 int const start ( *it );
1429 int const stop ( *it_next );
1430 int const label ( -2 );
1436 Int_list::iterator last_jump_it = jump_list.end();
1437 int const jump_start( *(--last_jump_it) );
1438 if (jump_start < nres_in) add_edge( jump_start, nres_in, Edge::PEPTIDE );
1440 assert( edge_list_[0].
start() == 1 &&
1441 edge_list_[ edge_list_.size()-1 ].stop() == nres_in );
1444 for (
int i=1; i<= num_jump_in; ++i ) {
1445 add_edge( jump_point_in(1,i), jump_point_in(2,i), i );
1449 int const num_user_cut_points = obligate_cut_points.size();
1450 for (
int i = 0; i < num_user_cut_points; i++ ) {
1451 int const cut_point = obligate_cut_points[i];
1452 bool const success = cut_edge( cut_point );
1464 bool is_a_tree (
false );
1465 while ( ! is_a_tree ) {
1466 update_edge_labels();
1468 for ( iterator it = edge_list_.begin(), it_end = edge_list_.end();
1469 it != it_end; ++it ) {
1470 if ( it->label() == -2 ) {
1476 if ( ! is_a_tree ) {
1477 if ( ! cut_random_edge( cut_bias_sum, nres_in ) ) {
1479 TR.Error <<
"failure in FoldTree::choose_random_cuts(...)." << std::endl;
1492 return check_fold_tree();
1497 bool FoldTree::cut_edge(
int const cut_point ) {
1499 for (
iterator it = edge_list_.begin(), it_end = edge_list_.end();
1500 it != it_end; ++it ) {
1501 if ( it ->label() < 0 &&
1502 ( ( it->start() <= cut_point && it->stop() >= cut_point+1 ) ||
1503 ( it->stop() <= cut_point && it->start() >= cut_point+1 ) ) ) {
1504 if ( it->label() == Edge::PEPTIDE ) {
1508 assert( it->label() == -2 );
1509 TR.Debug <<
"cutting at " << cut_point << std::endl;
1511 int const start( std::min( it->start(), it->stop()) );
1512 int const stop ( std::max( it->start(), it->stop()) );
1514 if ( start < cut_point ) add_edge( start, cut_point, Edge::PEPTIDE);
1515 if ( cut_point+1 < stop ) add_edge( cut_point+1, stop, Edge::PEPTIDE);
1527 FoldTree::cutpoints()
const
1531 for(
int i=1; i<= num_cutpoint_; ++i ) {
1532 cuts.push_back( cutpoint_[i] );
1560 FoldTree::update_edge_labels()
1562 assert( Edge::PEPTIDE != -2 );
1563 for (
iterator it = edge_list_.begin(), it_end = edge_list_.end();
1564 it != it_end; ++it ) {
1565 if ( it->label() == -2 ) {
1567 if ( ! connected() ) {
1568 it->label() = Edge::PEPTIDE;
1572 }
else if ( it->label() == 0 ) {
1573 TR.Fatal <<
"zero edge label in graph:" << std::endl;
1587 FoldTree::cut_random_edge(
1588 FArray1D_float
const & cut_bias_sum,
1594 while ( tries < 100000 ) {
1598 bool success = cut_edge( cut_point );
1599 TR.Debug <<
"Trying cut_point: " << cut_point <<
" " << success << std::endl;
1600 if (success )
return true;
1613 FoldTree::renumber_jumps()
1616 new_topology =
true;
1617 for (
iterator it = edge_list_.begin(), it_end = edge_list_.end();
1618 it != it_end; ++it ) {
1619 if ( it->is_jump() ) {
1621 TR.Debug <<
"renumber jumps:: from,to " << it->label() <<
' ' <<
1622 counter << std::endl;
1623 it->label() = counter;
1633 FoldTree::connected()
const
1635 static FArray1D_bool linked;
1636 if ( new_topology ) update_nres();
1637 if (
int( linked.size1() ) != nres_ ) linked.dimension( nres_ );
1639 if ( edge_list_.size() <1 )
return true;
1648 linked( it_begin->start() ) =
true;
1650 bool new_member (
true );
1652 while ( new_member ) {
1655 if ( it->label() == 0 )
continue;
1656 if ( linked( it->start() ) && ! linked( it->stop()) ) {
1657 linked(it->stop()) =
true;
1659 }
else if ( linked( it->stop() ) && ! linked( it->start() ) ) {
1660 linked( it->start() ) =
true;
1667 if ( ! linked( it->start() ) || ! linked( it->stop() ) ) {
1683 FoldTree::partition_by_jump(
1684 int const jump_number,
1692 FArray1D_bool partner1( nres_,
false );
1693 partition_by_jump( jump_number, partner1 );
1699 Size nres1(0), nres2(0);
1701 for (
Size i=1; i<=
Size(nres_); ++i ) {
1702 if ( partner1(i) ) {
1713 for (
const_iterator it=edge_list_.begin(), ite=edge_list_.end(); it != ite; ++it ) {
1715 if ( edge.
is_jump() && edge.
label() == jump_number )
continue;
1717 if ( partner1( edge.
start() ) ) {
1718 assert( partner1( edge.
stop() ) );
1721 edge.
stop () = seqpos1[ edge.
stop () ];
1725 edge.
label() = jump1;
1730 assert( !partner1( edge.
stop() ) );
1733 edge.
stop () = seqpos2[ edge.
stop () ];
1737 edge.
label() = jump2;
1753 FoldTree::partition_by_jump(
1754 int const jump_number,
1755 FArray1D_bool & partner1
1760 assert( jump_number <= num_jump_ );
1761 assert(
int(partner1.size1()) >= nres_ );
1764 int const pos1( jump_point_[jump_number ].first );
1771 partner1( pos1 ) =
true;
1773 bool new_member (
true );
1782 const_iterator it_begin( edge_list_.begin() );
1783 const_iterator it_end ( edge_list_.end() );
1785 while ( new_member ) {
1787 for ( const_iterator it = it_begin; it != it_end; ++it ) {
1788 if ( it->label() == jump_number )
continue;
1790 int const start( std::min( it->start(), it->stop() ) );
1791 int const stop ( std::max( it->start(), it->stop() ) );
1792 if ( (partner1(
start ) && !partner1(
stop )) ||
1793 (partner1(
stop ) && !partner1(
start )) ) {
1795 if ( it->is_polymer() ) {
1798 partner1( i ) =
true;
1802 partner1(
start ) =
true;
1803 partner1(
stop ) =
true;
1818 FoldTree::partition_by_residue(
1820 FArray1D_bool & partner1
1825 assert( seqpos <= nres_ );
1826 assert(
int(partner1.size1()) >= nres_ );
1835 bool found_edge(
false );
1836 partner1( seqpos ) =
true;
1839 int const start( std::min( it->start(), it->stop() ) );
1840 int const stop ( std::max( it->start(), it->stop() ) );
1841 if ( it->is_polymer() && start <= seqpos && stop >= seqpos ) {
1846 int const seqpos_edge_start( std::min( edge.
start(), edge.
stop() ) );
1847 for (
int i = seqpos_edge_start; i< seqpos; ++i ) partner1( i ) =
true;
1851 if (!found_edge)
return;
1853 bool new_member (
true );
1865 while ( new_member ) {
1869 int const start( std::min( it->start(), it->stop() ) );
1870 int const stop ( std::max( it->start(), it->stop() ) );
1872 if ( it->is_polymer() && start <= seqpos && stop >= seqpos )
continue;
1874 if ( ( partner1( start ) && !partner1( stop ) ) ||
1875 ( partner1( stop ) && !partner1( start ) ) ) {
1877 if ( it->is_polymer() ) {
1879 for (
int i=start; i<=
stop; ++i ) {
1880 partner1( i ) =
true;
1884 partner1( start ) =
true;
1885 partner1( stop ) =
true;
1894 FoldTree::jump_point(
1895 int const lower_higher,
1896 int const jump_number
1899 PyAssert(((jump_number > 0) || (jump_number <= num_jump_)),
1900 "FoldTree::jump_point( int const lower_higher, int const jump_number ): Input variable jump_number is not a valid value.");
1902 if( lower_higher == 1 ) {
1903 return jump_point_[jump_number].first;
1904 }
else if( lower_higher == 2 ) {
1905 return jump_point_[jump_number].second;
1907 std::cout <<
"FoldTree::jump_point() lower_higher needs to be 1 or 2" << std::endl;
1926 FoldTree::cutpoint_by_jump(
1927 int const jump_number
1932 FArray1D_bool partner1( nres_,
false );
1933 partition_by_jump( jump_number, partner1 );
1935 while ( i < nres_ && partner1(i) == partner1(i+1) ) i++;
1937 TR.Fatal <<
" FoldTree::cutpoint_by_jump error: "
1938 <<
"can not find the cutpoint! for jump_number: " << jump_number
1939 << std::endl << (*this) << std::endl;
1963 FoldTree::setup_edge_counts()
const
1966 if ( (
int)edge_count.size() != nres_ ) {
1969 if ( (
int)jump_edge_count.size() != num_jump_ ) {
1973 std::fill( edge_count.begin(), edge_count.end(), 0 );
1974 std::fill( jump_edge_count.begin(), jump_edge_count.end(), -1 );
1976 min_edge_count = nres_;
1980 FArray1D_bool linked(nres_);
1984 int const begin_res ( std::min( it->start(), it->stop()) );
1986 linked( begin_res ) =
true;
1990 bool new_member =
true;
1991 while ( new_member ) {
1995 if ( it2 == it )
continue;
1996 int const start ( std::min( it2->start(), it2->stop() ) );
1997 int const stop ( std::max( it2->start(), it2->stop() ) );
1999 if ( linked(start) && !linked(stop) ) {
2001 }
else if ( linked(stop) && !linked(start) ) {
2004 if ( new_link > 0 ) {
2006 linked(new_link) =
true;
2009 ( it2->is_jump() ) ? 1 : stop - start;
2014 if ( it->is_jump() ) {
2016 int const jump_number ( it->label() );
2017 jump_edge_count[ jump_number ] = link_count + 1;
2018 min_edge_count = std::min( min_edge_count, std::max(
2019 jump_edge_count[ jump_number ],
2020 nres_ - jump_edge_count[ jump_number ] ) );
2023 int const end_res ( std::max(it->start(), it->stop()) );
2025 for (
int i= begin_res+1; i<= end_res; ++i ) {
2026 edge_count[i] = link_count + i - begin_res;
2027 min_edge_count = std::min( min_edge_count, std::max(
2028 edge_count[i], nres_ - edge_count[i] ) );
2033 for (
int i=1; i<= num_jump_; ++i ) assert( jump_edge_count[ i ] >= 1 );
2052 FoldTree::get_residue_direction( int const seqpos ) const
2054 // the root residue is special
2055 if ( seqpos == begin()->start() ) return dir_jump;
2057 for ( const_iterator it = begin(), it_end = end(); it != it_end; ++it ) {
2058 if ( !it->is_polymer() ) {
2060 if ( seqpos == it->stop() ) {
2065 if ( seqpos > it->start() && seqpos <= it->stop() ) {
2066 return 1; // forward
2067 } else if ( seqpos < it->start() && seqpos >= it->stop() ) {
2068 return -1; // backward
2072 utility_exit_with_message( "no edge found that contains seqpos!" );
2079 FoldTree::jump_edge(
int const jump_number )
const
2081 PyAssert(((jump_number > 0) || (jump_number <= num_jump_)),
2082 "FoldTree::jump_edge( int const jump_number ): Input variable jump_number is not a valid value.");
2084 return edge_list_[ jump_edge_[ jump_number ] ];
2089 FoldTree::jump_edge(
int const jump_number )
2091 PyAssert(((jump_number > 0) || (jump_number <= num_jump_)),
2092 "FoldTree::jump_edge( int const jump_number ): Input variable jump_number is not a valid value.");
2094 return edge_list_[ jump_edge_[ jump_number ] ];
2099 FoldTree::get_residue_edge(
int const seqpos )
const
2101 if ( seqpos == root() ) utility_exit_with_message(
"FoldTree:: residue_edge is undefined for root vertex" );
2104 if ( seqpos == it->stop() ||
2105 ( it->is_peptide() &&
2106 ( ( seqpos > it->start() && seqpos <= it->stop() ) ||
2107 ( seqpos < it->
start() && seqpos >= it->stop() ) ) ) ) {
2111 utility_exit_with_message(
"no edge found that contains seqpos!" );
2117 FoldTree::get_outgoing_edges(
int const seqpos )
const
2122 if ( (it->start() == seqpos && it->stop() != seqpos) ||
2123 ( it->is_polymer() && ( ( seqpos >= it->start() && seqpos < it->stop() ) ||
2124 ( seqpos <= it->
start() && seqpos > it->stop() ) ) ) ) {
2125 outgoing.push_back( *it );
2137 FoldTree::get_polymer_residue_direction(
int const seqpos )
const
2140 if ( it->is_peptide() ) {
2142 if ( seqpos > it->start() && seqpos <= it->stop() ) {
2144 }
else if ( seqpos < it->
start() && seqpos >= it->stop() ) {
2149 utility_exit_with_message(
"no peptide edge found that contains (builds) seqpos!" );
2157 FoldTree::update_cutpoints()
const
2161 is_cutpoint_.dimension( DRange(0,nres_) );
2162 is_cutpoint_ =
true;
2166 it_end = edge_list_.end(); it != it_end; ++it ) {
2167 if ( it->is_polymer() ) {
2168 for (
int j = std::min( it->start(), it->stop() ),
2169 j_end = std::max( it->start(), it->stop() ); j < j_end; ++j ) {
2170 is_cutpoint_(j) =
false;
2174 assert( is_cutpoint_( 0 ) && is_cutpoint_( nres_ ) );
2180 for (
int i = 1; i < nres_; ++i ) {
2181 if ( is_cutpoint_(i) ) {
2190 for (
int i = 1, cut=0; i < nres_; ++i ) {
2191 if ( is_cutpoint_(i) ) {
2192 cutpoint_[ ++cut ] = i;
2193 cutpoint_map_[ i ] = cut;
2195 assert( i<nres_-1 || cut == num_cutpoint_ );
2205 FoldTree::update_nres()
const
2208 for (
const_iterator it = edge_list_.begin(), it_end = edge_list_.end();
2209 it != it_end; ++it ) {
2210 tmp_nres = std::max( tmp_nres, std::max( it->start(), it->stop()) );
2212 if ( tmp_nres != nres_ ) {
2223 FoldTree::update_num_jump()
const
2225 int tmp_num_jump (0);
2226 int biggest_label (0);
2227 for (
const_iterator it = edge_list_.begin(), it_end = edge_list_.end();
2228 it != it_end; ++it ) {
2229 if ( it->is_jump() ) {
2231 biggest_label = std::max( biggest_label, it->label() );
2235 if ( biggest_label != tmp_num_jump ) {
2236 TR.Fatal <<
"problem with the fold_tree: biggest_label != num_jump " <<
2237 biggest_label <<
' ' << tmp_num_jump << std::endl;
2242 if ( tmp_num_jump != num_jump_ ) {
2245 num_jump_ = tmp_num_jump;
2255 FoldTree::update_jump_points()
const
2258 if ( (
int)is_jump_point_.size() != nres_ ) {
2261 std::fill(is_jump_point_.begin(), is_jump_point_.end(),
false);
2263 if ( (
int)jump_point_.size() != num_jump_ ) {
2267 for (
const_iterator it = edge_list_.begin(), it_end = edge_list_.end();
2268 it != it_end; ++it ) {
2269 if ( it->is_jump() ) {
2270 int const jump_number ( it->label() );
2271 assert( jump_number <= num_jump_ );
2273 is_jump_point_[ it->start() ] =
true;
2274 is_jump_point_[ it->stop () ] =
true;
2276 jump_point_[jump_number].first = std::min( it->start(), it->stop());
2277 jump_point_[jump_number].second = std::max( it->start(), it->stop());
2278 }
else if ( it->is_chemical_bond() ) {
2281 is_jump_point_[ it->start() ] =
true;
2282 is_jump_point_[ it->stop () ] =
true;
2299 FoldTree::update_jump_edge()
const
2301 if ( (
int)jump_edge_.size() != num_jump_ ) {
2305 for (
const_iterator it = edge_list_.begin(), it_end = edge_list_.end();
2306 it != it_end; ++it, ++jump_index ) {
2307 if ( it->is_jump() ) {
2308 int const jump_number ( it->label() );
2309 assert( jump_number <= num_jump_ );
2310 assert( edge_list_[ jump_index ] == *it );
2312 jump_edge_[ jump_number ] = jump_index;
2318 FoldTree::show(std::ostream & out)
const
2320 out <<
" Edge \t Jump Jump #\n";
2322 it != it_end; ++it ) {
2324 if (it->is_jump()) {
2325 out <<
" \t" << I(4,4,it->start()) <<
"--" << I(4,4,it->stop()) <<
" " << I(3,3,it->label()) <<
'\n';
2327 out << I(4,4,it->start()) <<
"--" << I(4,4,it->stop()) <<
'\n';
2342 it != it_end; ++it ) {
2364 if ( !is.fail() && tag ==
"FOLD_TREE" ) {
2365 while ( !is.fail() ) {
2368 if ( is.fail() )
break;
2375 is.setstate( std::ios_base::failbit );
2376 TR.Error <<
"no fold_tree info in this stream." << std::endl;
2379 TR.Error <<
"bad fold_tree, reordering." << std::endl;
2382 TR.Error <<
"bad fold_tree still bad" << std::endl;
2396 FoldTree::check_fold_tree()
const
2398 if ( edge_list_.size() <= 0 )
return false;
2399 static FArray1D_bool seen;
2400 if ( new_topology ) update_nres();
2401 if (
int( seen.size1() ) != nres_ ) seen.dimension( nres_ );
2405 seen( it->start() ) =
true;
2406 for (
const_iterator it_end = edge_list_.end(); it != it_end; ++it ) {
2407 int const start( it->start() );
2408 int const stop ( it->stop() );
2410 TR.Error <<
"bad fold tree at edge " <<
start <<
"--" <<
stop <<
" !" << std::endl << *
this << std::endl;
2414 if ( !it->is_polymer() ) {
2415 seen(
stop ) =
true;
2418 for (
int i=
start + dir; i!=
stop + dir; i+= dir ) {
2420 TR.Error <<
"bad fold tree2!" << std::endl << *
this << std::endl;
2430 for (
int i=1; i<= nres_; ++i ) {
2432 TR.Error <<
"bad fold tree3!" << std::endl << *
this << std::endl;
2440 FoldTree::check_edges_for_atom_info()
const
2445 for (
const_iterator it_end = edge_list_.end(); it != it_end; ++it ) {
2446 if (it->label()== -2 && ! it->has_atom_info()){
2447 TR<<
"bad chemical edge from"<< it->start() <<
" to "<< it->stop();
2460 FoldTree::set_jump_atoms(
2461 int const jump_number,
2464 bool bKeepStubInResidue
2467 Edge & edge( jump_edge( jump_number ) );
2472 assert( ( upstream_atom.size() && downstream_atom.size() )
2473 || ( !upstream_atom.size() && !downstream_atom.size() ) );
2480 FoldTree::set_jump_atoms(
2481 int const jump_number,
2486 bool bKeepStubInResidue
2489 runtime_assert( res1 != res2 );
2490 Edge & edge( jump_edge( jump_number ) );
2494 runtime_assert(
Size(edge.
stop()) == res1 );
2501 runtime_assert(
Size(edge.
stop()) == res2 );
2507 assert( ( atom1.size() && atom2.size() )
2508 || ( !atom1.size() && !atom2.size() ) );
2518 FoldTree::upstream_atom(
int const jump_number )
const
2520 Edge const & edge( jump_edge( jump_number ) );
2536 FoldTree::downstream_atom(
int const jump_number )
const
2538 Edge const & edge( jump_edge( jump_number ) );
2556 FoldTree::count_fixed_residues(
2557 Size const begin_res,
2559 Size & min_edge_count_out
2568 min_edge_count_out = min_edge_count;
2570 Size const end_res ( begin_res + size - 1);
2571 assert( begin_res >= 1 && end_res <= static_cast<Size> ( nres_ ) );
2574 if ( ! is_cutpoint_( begin_res-1 ) ) {
2575 int const n_fixed ( edge_count[ begin_res ] );
2576 if ( n_fixed > best ) {
2581 if ( ! is_cutpoint_( end_res ) ) {
2582 int const c_fixed ( nres_ - edge_count[ end_res + 1] );
2583 if ( c_fixed > best ) {
2589 for (
int i = 1; i<= num_jump_; ++i ) {
2590 for (
int j = 1; j <= 2; ++j ) {
2591 Size const pos = j == 1 ? jump_point_[i].first : jump_point_[i].second;
2592 if ( begin_res <= pos && pos <= end_res ) {
2594 ( j==1 ? nres_ - jump_edge_count[ i ] : jump_edge_count[ i ] );
2595 if ( fixed > best ) {
2604 void FoldTree::reassign_atoms_for_intra_residue_stubs() {
2605 assert( check_fold_tree() );
2607 for (
Size jump_nr = 1; jump_nr <= num_jump(); ++jump_nr ) {
2608 if ( !jump_edge( jump_nr ).keep_stub_in_residue() )
continue;
2612 if ( jump_edge( jump_nr ).start() == root() ) {
2616 Edge anchor_edge = get_residue_edge( jump_edge( jump_nr ).
start() );
2619 if ( !anchor_edge.
is_jump() ) {
2620 bool bN2C = anchor_edge.
start() < anchor_edge.
stop();
2635 TR.Debug <<
"set anchor and root atom for jump " << jump_nr <<
" to " << anchor <<
" and " << root << std::endl;
2638 if ( upstream_atom_name !=
"" && upstream_atom_name !=
"N" && upstream_atom_name !=
"C" && upstream_atom_name !=
"CA" ) {
2639 std::cout <<
"UPSTREAM_ATOM_NAME" << upstream_atom_name << std::endl;
2640 anchor = upstream_atom_name;
2643 if ( downstream_atom_name !=
"" && downstream_atom_name !=
"N" && downstream_atom_name !=
"C" && downstream_atom_name !=
"CA" ){
2644 std::cout <<
"DOWNSTREAM_ATOM_NAME" << downstream_atom_name << std::endl;
2645 root = downstream_atom_name;
2648 set_jump_atoms( jump_nr, anchor, root,
true );
2652 void FoldTree::put_jump_stubs_intra_residue() {
2654 assert( check_fold_tree() );
2655 for (
Size jump_nr = 1; jump_nr <= num_jump(); ++jump_nr ) {
2656 if ( ! jump_edge( jump_nr ).has_atom_info() ) {
2657 jump_edge( jump_nr ).keep_stub_in_residue() =
true;
2660 reassign_atoms_for_intra_residue_stubs();