35 #include <basic/Tracer.hh>
37 #include <utility/excn/Exceptions.hh>
40 #include <numeric/random/random.hh>
45 #include <utility/vector1.hh>
47 #include <ObjexxFCL/format.hh>
51 namespace kinematics {
54 static numeric::random::RandomGenerator
RG(62457);
55 static basic::Tracer
TR(
"core.kinematics.util");
76 bool const add_jump_atom
82 AtomOP const atom_p( add_jump_atom ? static_cast< Atom* >(
new JumpAtom()) : static_cast< Atom* >(
new BondedAtom()));
83 atom_p->set_weak_ptr_to_self( atom_p() );
86 assert( atom_ptr[ atomno ] == 0 );
87 atom_ptr[ atomno ] = atom_p;
90 atom_p->id(
AtomID( atomno, seqpos ) );
94 for (
Size i=1, i_end = nbrs.size(); i<= i_end; ++i ) {
95 int const nbr( nbrs[i] );
96 if ( atom_ptr[ nbr ] != 0 )
continue;
97 atom_p->append_atom(
add_atom( nbr, seqpos, links, atom_ptr,
false ));
113 ObjexxFCL::FArray1D_float
const & cut_bias_sum
117 float r =
RG.uniform() * cut_bias_sum( n_res );
121 for (
Size i = 1; i <= n_res; ++i ) {
122 if ( r > cut_bias_sum(i-1) && r <= cut_bias_sum(i) ) {
127 if ( cutpoint == 0 ) {
128 TR.Warning <<
"pick loopy cutpoint = 0! setting = 1" << std::endl;
145 utility_exit_with_message(
"needs to be refactored to meet new tree-building guidelines");
190 utility_exit_with_message(
"This code needs to be refactored to use AtomOPs" );
222 // map from each mainchain_atom to the (possibly empty) list of pseudo-residues
223 vector1< vector1< Size > > mainchain_to_pseudo( nbb );
225 vector1< bool > seen( nbb, false );
227 vector1< Atom* > mainchain_atom_pointer( nbb, 0 );
228 vector1< Atom* > pseudo_atom_pointer( edges.size(), 0 );
230 // create the root of the tree
231 AtomOP root( setup_cloned_atom( old_atom_pointer[ mainchain[1] ], mainchain ) );
232 mainchain_atom_pointer[ 1 ] = root;
235 while ( n < edges.size() ) {
237 std::pair< Size, Size > const & edge( edges[n] );
239 Size const a( edge.first );
240 Size const b( edge.second );
243 // what should our anchor atom be?
244 // look at all pseudo rsds associated to a
247 vector1< Size > const & pseudo_a( mainchain_to_pseudo[a] );
248 for ( Size i=1; i<= pseudo_a.size(); ++i ) {
249 Size const nn( pseudo_a[i] );
250 assert( edges[nn].second == a );
251 if ( ( edges[nn].first < b && b < a ) || ( edges[nn].first > b && b > a ) ) {
252 anchor = nn; // dont break -- want the smallest segment containing a,b
256 anchor_atom = pseudo_atom_pointer[ anchor ];
258 // connect to the authentic a
259 anchor_atom = mainchain_atom_pointer[ a ];
262 // has b been seen before?
263 AtomCOP old_b_atom( old_atom_pointer[ mainchain[b] ] );
266 // add b and b's non-mainchain children
267 Atom* b_atom( setup_cloned_atom( old_b_atom, mainchain ) );
268 anchor_atom->insert_atom( b_atom ); // NOTE: insert atom
269 mainchain_atom_pointer[ b ] = b_atom;
273 // add a new pseudo rsd at b's position
274 mainchain_to_pseudo[ b ].push_back( n );
275 Size const pseudo_b_seqpos( first_new_pseudo_residue + n - 1 );
276 AtomID const pseudo_b_id( AtomID( 1, pseudo_b_seqpos ) );
277 // delete the old one
278 Atom* old_pseudo_b_atom( old_atom_pointer[ pseudo_b_id ] );
279 old_pseudo_b_atom->parent()->delete_atom( old_pseudo_b_atom );
280 delete old_pseudo_b_atom;
282 Atom* pseudo_b_atom( new BondedAtom() );
283 pseudo_b_atom->id( pseudo_b_id );
284 pseudo_b_atom->xyz( old_b_atom->xyz() + pseudo_offset );
285 anchor_atom->append_atom( pseudo_b_atom );
286 pseudo_atom_pointer[ n ] = pseudo_b_atom;
287 std::cout << "new pseudo! " << n << ' ' << a << ' ' << b << ' ' << mainchain[a] << ' ' << mainchain[b] << ' ' <<
288 pseudo_b_seqpos << ' ' << old_b_atom->id() << ' ' <<
289 old_b_atom->xyz()[0] << ' ' <<
290 old_b_atom->xyz()[1] << ' ' <<
291 old_b_atom->xyz()[2] << std::endl;
293 // check if this edge is terminal, if so add all intervening mainchain atoms and their children
295 bool terminal( true );
296 for ( Size n2=n+1; n2<= edges.size(); ++n2 ) {
297 if ( ( edges[n2].first == b ) &&
298 ( a < b && edges[n2].second < b || a > b && edges[n2].second > b ) ) {
304 int const dir( b<a ? 1 : -1 );
305 AtomOP parent_atom( pseudo_b_atom );
306 for ( int c=b+dir; c != (int)a; c += dir ) {
309 // add c and c's non-mainchain children
310 AtomCOP old_c_atom( old_atom_pointer[ mainchain[c] ] );
311 Atom* c_atom( setup_cloned_atom( old_c_atom, mainchain ) );
312 parent_atom->insert_atom( c_atom ); // at front of list since this is mainchain. may have already added kids
313 mainchain_atom_pointer[ c ] = c_atom;
316 parent_atom = c_atom;
318 } // walk from b->a adding the mainchain atoms and their children to the tree
325 } // loop over edges, add one pseudo rsd for each edge
327 // confirm that all mainchain atoms have been seen
328 for ( Size i=1; i<= nbb; ++i ) {
340 for (
Size pos = 1; pos <= fold_tree.
nres(); pos++ ) {
341 bool special(
false );
345 if ( special ) out <<
"/";
352 if ( special ) out <<
"/";
356 if (!special ) out <<
"*";
368 for (
Size pos = 1; pos <= fold_tree.
nres(); pos++ ) {
369 bool special(
false );
375 move.push_back(
'.' );
378 move.push_back( mm.
get_bb( pos ) ?
'*' :
'x' );
386 move.push_back(
'.' );
389 move.push_back( mm.
get_bb( pos ) ?
'*' :
'x' );
394 move.push_back( mm.
get_bb( pos ) ?
'*' :
'x' );
408 for (
Size pos = 1; pos <= fold_tree.
nres(); pos++ ) {
409 bool special(
false );
415 move.push_back(
'.' );
418 move.push_back( mm.
get_bb( pos ) ?
'*' :
'x' );
419 move_chi.push_back( mm.
get_chi( pos ) ?
'*' :
'x' );
427 move.push_back(
'.' );
428 move.push_back(
'.' );
431 move.push_back( mm.
get_bb( pos ) ?
'*' :
'x' );
432 move_chi.push_back( mm.
get_chi( pos ) ?
'*' :
'x' );
437 move_chi.push_back( mm.
get_chi( pos ) ?
'*' :
'x' );
438 move.push_back( mm.
get_bb( pos ) ?
'*' :
'x' );
441 out <<
"\n" << move <<
"\n" << move_chi;
454 if( !it->is_jump() ) newtree.
add_edge(*it);
470 size_t start_pos = 0;
471 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
472 str.replace(start_pos, from.length(), to);
473 start_pos += to.length();
479 r.reserve(n * s.size());
480 for (
size_t i=0; i<n; i++) r += s;
486 int topad = npad-s.size();
493 int topad = npad-s.size();
499 int topad = npad-s.size();
506 : name(_name), jnum(_jnum), jumpfrom(_jumpfrom), jumpto(_jumpto), prefix_len(8), follows(_follows), jumpmark(_jumpmark), parent(NULL) {}
514 using ObjexxFCL::string_of;
518 string mark = ((*ic)->jumpmark==(char)NULL) ?
"-" :
string(
"")+(*ic)->jumpmark;
519 string vchar = children.size()==1 ?
"" : (*ic==children.back() ?
" " :
"|");
520 string schar = children.size()==1 ?
"" : (*ic==children.back() ?
"\\" :
"|");
524 if( (*ic)->follows!=0 ) {
525 jstr =
"j" + string_of((*ic)->jnum) + ( ((*ic)->follows) ?
"="+string_of((*ic)->follows) :
"" );
527 jstr = mark +
"j" + string_of((*ic)->jnum) + mark;
530 string news = (*ic)->str();
531 string pad =
string(
" ")*(prefix.size()-1);
532 if(children.size()==1) pad +=
string(
" ")*(name.size()+1);
534 if(children.size()==1) s += prefix+news;
535 else s +=
"\n"+prefix+news;
552 lb_.resize(ft.nres(),0);
553 ub_.resize(ft.nres(),0);
558 lb_[res]=1, ub_[res]=ft.nres();
559 for(
int i = 1; i <= ft.num_cutpoint(); ++i) {
561 if( c < res ) lb_[res] = std::max(lb_[res],c+1);
562 if( c >= res ) ub_[res] = std::min(ub_[res],c );
570 Size lb,ub; get_ft_node_bounds(res,lb,ub);
575 Size lb,ub; get_ft_node_bounds(res,lb,ub);
581 Size lb,ub; get_ft_node_bounds(res,lb,ub);
582 for(
Size i = 1; i <= ft.num_jump(); ++i){
583 Size dn = ft.downstream_jump_residue(i);
584 if( lb <= dn && dn <= ub )
return dn;
591 for(std::map<Size,std::string>::iterator i = node_labels_partial.begin(); i != node_labels_partial.end(); ++i) {
592 tocheck.push_back(i->first);
596 if( *i == *j )
continue;
598 if( get_ft_node_lower_bound(*i) == get_ft_node_lower_bound(*j) ) {
599 if(node_labels_partial[*i] != node_labels_partial[*j]) {
600 utility_exit_with_message(
"non-matching node_labels_partial requested in same FT contig");
604 Size lb,ub; get_ft_node_bounds(*i,lb,ub);
605 for(
Size ir = lb; ir <= ub; ++ir) {
606 node_labels_partial[ir] = node_labels_partial[*i];
613 using ObjexxFCL::fmt::I;
615 if( ft.nres() > 9 ) npad = 2;
616 if( ft.nres() > 99 ) npad = 3;
617 if( ft.nres() > 999 ) npad = 4;
618 if( ft.nres() > 9999 ) npad = 5;
621 for(
Size i = 1; i <= ft.nres(); ++i) {
622 Size lb,ub; get_ft_node_bounds(i,lb,ub);
623 std::string lbl = node_labels_partial.count(lb) ? node_labels_partial[lb] :
"Contig";
626 std::string resrange = I(npad,lb) + ((ub==lb)?
"":
"-"+I(npad,ub));
627 names[i] = lbl +
"(" + resrange +
")";
633 Size lb,ub; get_ft_node_bounds(resi,lb,ub);
634 for(
Size i=1; i <= ft.num_jump(); ++i) {
635 if( lb <= (
Size)ft.downstream_jump_residue(i) && (
Size)ft.downstream_jump_residue(i) <= ub )
return i;
645 std::map<Size,std::string>
const & node_labels_partial_in,
646 std::map<Size,char>
const & mark_jump_to_res,
647 std::map<Size,Size>
const & jump_follows
651 std::map<Size,std::string> node_labels_partial(node_labels_partial_in);
656 std::map<std::string,Node*> nodemap;
657 for(
Size ir = 1; ir <= ft.
nres(); ++ir) {
658 if( nodemap.count(res_to_nodename[ir]) )
continue;
661 Size jumpfrom = (jnum&&!tvb.
is_single(ft. upstream_jump_residue(jnum))) ? ft. upstream_jump_residue(jnum) : 0;
663 char markjump = (char)NULL;
664 for(
Size jr = lb; jr <= ub; ++jr)
if(mark_jump_to_res.count(jr)) markjump = mark_jump_to_res.find(jr)->second;
665 Size follows = jump_follows.find(jnum)!=jump_follows.end() ? jump_follows.find(jnum)->second : (
Size)0;
666 nodemap[res_to_nodename[ir]] =
new Node(res_to_nodename[ir],jnum,jumpfrom,jumpto,markjump,follows);
670 std::string up = res_to_nodename[ft. upstream_jump_residue(i)];
674 utility_exit_with_message(
"BAD FOLD TREE NODES!!!!!!!");
676 nodemap[dn]->setparent(nodemap[up]);
679 for(std::map<std::string,Node*>::const_iterator i = nodemap.begin(); i != nodemap.end(); ++i) {
680 std::string rootname0 = nodemap.begin()->second->root()->name;
681 if( rootname0 != i->second->root()->name ) utility_exit_with_message(
"Nodes not connected!!!");
687 return nodemap.begin()->second->root()->str();
691 std::map<Size,std::string> empty_labels;
692 std::map<Size,char> empty_marks;
693 std::map<Size,Size> empty_follows;
699 std::map<Size,char> empty_marks;
700 std::map<Size,Size> empty_follows;
706 std::map<Size,std::string> empty_labels;
707 std::map<Size,Size> empty_follows;
756 throw utility::excn::EXCN_Msg_Exception(
"FoldTree utility remodel_fold_tree_to_account_for_insertion: I do not know how to handle insertion points that are also jump points - does the jump stay where it was or move to the end of the insert?");
761 typedef std::vector< core::kinematics::Edge >
EdgeList;
762 typedef EdgeList::const_iterator ELconst_iterator;
764 for( ELconst_iterator it(input_tree.
begin()),
end(input_tree.
end()); it!=
end; ++it){
777 it->keep_stub_in_residue());