Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FoldTree.hh
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 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file core/kinematics/FoldTree.hh
11 /// @brief Fold tree class
12 /// @author Phil Bradley
13 
14 #ifndef INCLUDED_core_kinematics_FoldTree_hh
15 #define INCLUDED_core_kinematics_FoldTree_hh
16 
17 // Unit headers
19 
20 // Package Headers
21 #include <core/kinematics/Edge.hh>
22 
23 // utility headers
24 #include <core/types.hh>
26 #include <utility/vector1.hh>
27 #include <utility/pointer/ReferenceCount.hh>
28 
29 // ObjexxFCL Headers
30 #include <ObjexxFCL/FArray1D.hh>
31 #include <ObjexxFCL/FArray2D.hh>
32 
33 // Third-party Headers
34 #include <boost/functional/hash.hpp>
35 
36 // // C++ Headers
37 #include <string>
38 #include <vector>
39 #include <iostream>
40 
41 #ifdef PYROSETTA
43 #endif
44 
45 namespace core {
46 namespace kinematics {
47 
48 
49 /// @brief The FoldTree is a residue-based treelike representation of a molecule
50 ///
51 /// @note all the derived data is "mutable", so that we can
52 /// update them as needed on the fly inside "const" member functions
53 /// this emphasizes that the core data is just the edge_list_
54 ///
55 /// @note see @ref foldtree_overview "FoldTree overview and concepts" for details
56 ///
57 /// Common Methods:
58 /// FoldTree.check_fold_tree
59 /// FoldTree.clear
60 /// FoldTree.new_jump
61 /// FoldTree.nres
62 /// FoldTree.num_jump
63 /// FoldTree.simple_tree
64 /// Foldtree.size
66 {
67 
68 public:
69  //@brief Automatically generated virtual destructor for class deriving directly from ReferenceCount
70  virtual ~FoldTree();
71  // types
72  typedef std::vector< Edge > EdgeList;
73  typedef EdgeList::iterator iterator;
74  typedef EdgeList::const_iterator const_iterator;
75 
76  // MOVED TO CLASS Edge
77  //static int const PEPTIDE = -1; // must be negative, see Edge::is_jump()
78  //static int const CHEMICAL = -2; // for fold-tree edges that connect two chemically-bound residues
79 
80  /// @brief constructor
82  ReferenceCount(),
83  new_topology (true), // new_topology == true ==> new_order == true
84  nres_(0),
85  num_jump_(0)
86  {}
87 
88  /// @brief Constructs a simple FoldTree
89  ///
90  /// ft = FoldTree( nres_in )
91  ///
92  /// int nres_in /the number of residues in this simple tree
93  FoldTree( int const nres_in ):
94  ReferenceCount(),
95  new_topology (true), // new_topology == true ==> new_order == true
96  nres_(0),
97  num_jump_(0)
98  {
99  simple_tree( nres_in );
100  }
101 
102  /// @brief operator=
103  /// @note this version doesnt copy any of the derived data!
104  /// will this be too slow? it will trigger re-calculating of everything
105  /// every time we reject a move....
106  FoldTree & operator =( FoldTree const & src )
107  {
108  edge_list_ = src.edge_list_;
109  new_topology = true;
110  return *this;
111  }
112 
113  // non-modifying access /////////////////////////////////////////////////////
114 
115  /// @brief Returns the starting residue of the kinematic chunk to which res belongs
116  Size boundary_left(Size res) const {
117  assert(res > 0);
118  assert(res <= nres());
119  assert(!is_root( int(res) ) );
120  return get_residue_edge(int(res)).start();
121  }
122 
123  /// @brief Returns the ending residue of the kinematic chunk to which res belongs
124  Size boundary_right(Size res) const {
125  assert(res > 0);
126  assert(res <= nres());
127  assert(!is_root( int(res) ) );
128  return get_residue_edge(int(res)).stop();
129  }
130 
131 
132  /// @brief Returns the number of edges in the FoldTree
133  ///
134  /// example(s):
135  /// ft.size()
136  /// See also:
137  /// FoldTree
138  /// FoldTree.add_edge
139  /// FoldTree.check_fold_tree
140  /// FoldTree.delete_edge
141  /// FoldTree.jump_edge
142  /// FoldTree.nres
143  /// FoldTree.num_jump
144  inline
145  int
146  size() const
147  {
148  return int( edge_list_.size() );
149  }
150 
151  /// @brief begin iterator of the edge_list
152  inline
154  begin() const
155  {
156  return edge_list_.begin();
157  }
158 
159  /// @brief end iterator of the edge_list
160  inline
162  end() const
163  {
164  return edge_list_.end();
165  }
166 
167  /// @brief Displays the FoldTree information
168  ///
169  /// example(s):
170  /// ft.show()
171  /// See Also:
172  /// Pose
173  void
174  show( std::ostream & out ) const;
175 
176  // modifiers //////////////////////////////////////////////////////////
177  // add,delete edges:
178 
179  /// @brief Adds an edge from <start> to <stop>
180  void
181  add_edge(
182  int const start,
183  int const stop,
184  int const label
185  );
186 
187  /// @brief Especially useful version of add_edge for chemical edge construction
188  void
189  add_edge(
190  int const start,
191  int const stop,
192  std::string const & start_atom,
193  std::string const & stop_atom
194  );
195 
196  /// @brief Add the edge <new_edge>
197  ///
198  /// example(s):
199  /// ft.add_edge(edge1)
200  /// See also:
201  /// FoldTree
202  /// FoldTree.check_fold_tree
203  /// FoldTree.delete_edge
204  /// FoldTree.jump_edge
205  /// FoldTree.nres
206  /// FoldTree.num_jump
207  void
208  add_edge( Edge const & new_edge );
209 
210  /// @brief Deletes the edge <edge> in the FoldTree by iterator
211  void delete_edge( iterator edge );
212 
213  /// @brief Delete the edge <edge> in the fold tree by example edge
214  ///
215  /// example(s):
216  /// ft.delete_edge(edge1)
217  /// See also:
218  /// FoldTree
219  /// FoldTree.add_edge
220  /// FoldTree.check_fold_tree
221  /// FoldTree.jump_edge
222  /// FoldTree.nres
223  /// FoldTree.num_jump
224  void delete_edge( Edge const & edge );
225 
226  /// @brief Find an edge in fold tree and delete it
227  void delete_unordered_edge( int const start, int const stop,int const label);
228 
229  /// @brief Changes the label of an edge in fold tree
230  void update_edge_label( int const start, int const stop,
231  int const old_label, int const new_label );
232  /// @brief Returns the edge label of the edge from <start> to <stop>
233  int edge_label( int const start, int const stop );
234 
235  /// @brief Deletes all edge in the FoldTree
236  ///
237  /// example(s):
238  /// ft.clear()
239  /// See also:
240  /// FoldTree
241  /// FoldTree.add_edge
242  /// FoldTree.check_fold_tree
243  /// FoldTree.delete_edge
244  /// FoldTree.new_jump
245  /// FoldTree.nres
246  /// FoldTree.num_jump
247  /// FoldTree.simple_tree
248  /// FoldTree.size
249  void clear() {edge_list_.clear(); new_topology=true;}
250 
251  /// @brief Renumbers the jump edges in the FoldTree
252  /// How?
253  void renumber_jumps();
254 
255  /// @brief Deletes edges with start==stop
256  /// allowable 1->1 edge for single residue FoldTree
257  void delete_self_edges();
258 
259  /// @brief Delete vertices that are no longer necessary any more
260  /// How is this determined?
261  void delete_extra_vertices();
262 
263  /// @brief Deletes a continuous segment from <seq_begin> to <seq_end>
264  ///
265  /// example(s):
266  /// ft.delete_segment(13,37)
267  /// See also:
268  /// FoldTree
269  /// FoldTree.check_fold_tree
270  /// FoldTree.delete_edge
271  /// FoldTree.new_jump
272  /// FoldTree.nres
273  /// FoldTree.simple_tree
274  void delete_segment( int const seg_begin, int const seg_end );
275 
276  /// @brief Deletes the residue <seqpos> from the FoldTree.
277  /// Will rearrange topology if necessary.
278  ///
279  /// example(s):
280  /// ft.delete_seqpos(3)
281  /// See also:
282  /// FoldTree
283  /// FoldTree.check_fold_tree
284  /// FoldTree.clear
285  /// FoldTree.new_jump
286  /// FoldTree.nres
287  /// FoldTree.num_jump
288  /// FoldTree.simple_tree
289  void
290  delete_seqpos( int const seqpos );
291 
292  /// @brief Inserts a polymer residue at position <seqpos>
293  /// How?
294  void
296  int const seqpos,
297  bool const join_lower,
298  bool const join_upper
299  );
300 
301  /// @brief Inserts a residue attached only by a jump. precondition is that seqpos-1 is a cutpoint
302  /// @note that anchor_pos is wrt the current numbering system (ie before insertion)
303  void
305  int const seqpos,
306  int anchor_pos,
307  std::string const& anchor_atom = "",
308  std::string const& root_atomno = ""
309  );
310 
311  /// @brief Inserts a fold_tree as a subtree
312  void
314  FoldTree const & subtree,
315  int const insert_seqpos, // rsd 1 in subtree goes here
316  int const insert_jumppos, // jump 1 in subtree goes here
317  int const anchor_pos, // in the old numbering system
318  int anchor_jump_number = 0, // in the new jump numbering system, default=0
319  std::string const & anchor_atom = "", // could be ""
320  std::string const & root_atom = "" // ditto
321  );
322 
323  /// @brief Renumber all vertices according to an input sequence mapping
324  void
325  apply_sequence_mapping( id::SequenceMapping const & old2new );
326 
327  /// @brief Adds a new jump edge from <pos1> to <pos2> with cutpoint <cutpoint>
328  int new_jump( int const jump_pos1, int const jump_pos2,
329  int const cutpoint );
330 
331  void
333  int const anchor_pos,
334  int const root_pos,
335  std::string const & anchor_atom,
336  std::string const & root_atom,
337  int const new_cutpoint
338  );
339 
340  // ways to build an entire tree:
341 
342  /// @brief Produces a 1-edge FoldTree that is <nres_in> long
343  /// No jumps or extraneous features
344  ///
345  /// example(s):
346  /// ft.simple_tree()
347  /// See also:
348  /// FoldTree
349  /// FoldTree.add_edge
350  /// FoldTree.check_fold_tree
351  /// FoldTree.clear
352  /// FoldTree.delete_edge
353  /// FoldTree.is_simple_tree
354  /// FoldTree.new_jump
355  /// FoldTree.nres
356  /// FoldTree.num_jump
357  /// FoldTree.size
358  void simple_tree( int const nres_in ); // makes a 1-->total_residue tree
359 
360  /// @brief Returns true if the FoldTree has 1-edge (non-jump)
361  ///
362  /// example(s):
363  /// ft.is_simple_tree()
364  /// See also:
365  /// FoldTree
366  /// FoldTree.check_fold_tree
367  /// FoldTree.num_jump
368  /// FoldTree.simple_tree
369  bool is_simple_tree() const;
370 
371  /// @brief Builds a FoldTree from a list of <jump_points> and random cut
372  /// points based on some biased probability
373  /// Returns bool about success
375  int const nres_in, int const num_jump_in,
376  ObjexxFCL::FArray2D_int const & jump_point,
377  ObjexxFCL::FArray1D_float const & cut_bias,
378  int const root_in=1,
379  bool const allow_jump_at_1_or_NRES = false
380  );
381 
382  /// @brief Builds a FoldTree from a list of <jump_points> and random cut
383  /// points based on some biased probability and any user-defined obligate cutpoints
384  /// Returns bool about success
386  int const nres_in, int const num_jump_in,
387  ObjexxFCL::FArray2D_int const & jump_point,
388  std::vector< int > const & obligate_cut_points,
389  ObjexxFCL::FArray1D_float const & cut_bias,
390  int const root_in = 1,
391  bool const allow_jump_at_1_or_NRES = false );
392 
393  /// @brief Constructs a FoldTree from listed <jump point> and <cuts>
394  /// Returns bool about success
396  int const nres_in, int const num_jump_in,
397  ObjexxFCL::FArray2D_int const & jump_point,
398  ObjexxFCL::FArray1D_int const & cuts,
399  int const root_in = 1,
400  bool const verbose = false
401  );
402 
403  /// @brief Appends a new residue to the tree, either by a jump or as a continuation of a peptide segment
404  void
406  bool const attach_by_jump = false,
407  int const jump_anchor_residue = 0,
408  std::string const& jump_upstream_atom = "",
409  std::string const& jump_downstream_atom = ""
410  );
411 
412  /// @brief Appends a new residue to the tree using a chemical (APL-style) connection
413  void
415  int const anchor_residue,
416  std::string const& anchor_atom,
417  std::string const& root_atom
418  );
419 
420 
421  /// @brief Reorders the FoldTree to start at residue <start_residue>
422  bool reorder( int const start_residue );
423  // void refold_reorder( int const begin_res, int const end_res,
424  // ObjexxFCL::FArray1D_bool const & jump_moved );
425 
426 
427  // check status ////////////////////////////////////////////////////////
428  /// @brief Returns true if this is a valid FoldTree
429  ///
430  /// example(s):
431  /// ft.check_fold_tree()
432  /// See also:
433  /// FoldTree
434  /// FoldTree.check_fold_tree
435  /// FoldTree.clear
436  /// FoldTree.is_simple_tree
437  /// FoldTree.new_jump
438  /// FoldTree.nres
439  /// FoldTree.num_jump
440  /// FoldTree.simple_tree
441  bool check_fold_tree() const; // foldable?
442 
443  /// @brief Returns true if the FoldTree is connected
444  bool connected() const; // connected
445  /// @brief chemical edges should have atom info
446  bool check_edges_for_atom_info() const;
447  /// @brief the staring residue for this jump
448  int upstream_jump_residue( int const jump_number ) const;
449  /// @brief the stopping residue for this jump
450  int downstream_jump_residue( int const jump_number ) const;
451  /// partition into two foldtrees by cutting at jump= jump_number
452 
453  void
455  int const jump_number,
456  FoldTree & f1, //contains N-terminal vertex in jump, like partner1 in partition_by_jump below
457  FoldTree & f2
458  ) const;
459 
460  /// @brief partition the fold tree in two parts if the jump is disconnected.
461  void
463  int const jump_number,
464  ObjexxFCL::FArray1D_bool & partner1
465  ) const ;
466 
467  /// @brief partition the fold tree in two parts if a cut would be introduced between seqpos and seqpos+1
468  void
470  int const seqpos,
471  ObjexxFCL::FArray1D_bool & partner1
472  ) const ;
473 
474  /// @brief Returns the corresponding cutpoint position for jump <jump_number>
475  /// WARNING: if you look for all cutpoints by cycling thru jump_numbers you may be dissapointed
476  /// you will get most likely the same cutpoint for several different jump_numbers
477  /// however: the method cutpoint( nr ) will give you the number you are looking for
478  int
480  int const jump_number
481  ) const;
482 
483  // these routines are for storing extra information about the jumps
484  // you can specify which atoms should be the up/downstream atoms for
485  // each jump. Note that this assumes that the topology and order of the
486  // fold_tree are fixed, at least until this data is needed.
487  //
488  // the data are cleared upon re-ordering/wiring of the tree.
489 
490  /// @brief the jump atom on the staring side
492  upstream_atom( int const jump_number ) const;
493  /// @brief the jump atom on the stopping side
495  downstream_atom( int const jump_number ) const;
496 
497  /// @brief Returns the direction (n2c, c2n) in which the given (peptide) residue is built during folding.
498  int
499  get_polymer_residue_direction( int const seqpos ) const;
500 
501 
502  /// @brief Returns the edge that builds the residue <seqpos>
503  /// Does not work for root atom (will fail)
504  Edge const &
505  get_residue_edge( int const seqpos ) const;
506 
507  /// @brief Returns all edges that build a residue directly off of <seqpos>
509  get_outgoing_edges( int const seqpos ) const;
510 
511  /// @brief Get the number of the jump that builds (connects to) a given residue
512  int
513  get_jump_that_builds_residue( int const seqpos ) const;
514 
515  /// @brief define the specific atoms that should be connected by this jump
516  /**
517  This information can then be used in setting up the AtomTree from the
518  FoldTree. Data is stored in the Edge corresponding to this Jump.
519  If not specified, residue-specific defaults will be used.
520  */
521 
522 
523  void
525  int const jump_number,
526  std::string const& upstream_atom,
528  bool bKeepStubInResidue = false
529  );
530 
531  //version of above but makes it permutation safe!
532  //
533  void
535  int const jump_number,
536  core::Size res1,
537  std::string const& atom1,
538  core::Size res2,
539  std::string const& atom2,
540  bool bKeepStubInResidue = false
541  );
542 
543  /// @brief this reorganizes upstream/downstream atoms of all jumps such that
544  /// stubs are N-CA-C
546 
547  /// @brief this reorganizes upstream/downstream atoms of jumps that have flag
548  /// keep_stub_in_resiue = true such that
549  /// stubs are N-CA-C
551 
552 
553  // stream I/O //////////////////////////////////////////////////////////
554  // these two should be inverses!
555  // depend on I/O for the class: Edge
556 
557  /// @brief input operator
558  friend std::istream & operator >>(std::istream & is, FoldTree & t);
559  /// @brief output operator
560  friend std::ostream & operator <<(std::ostream & os, FoldTree const & t);
561 
562  ///////////////////////////// derived data //////////////////////
563  // routines for retrieving derived data, typically fast
564 
565  // @brief computes a fixed-length, hash-based identifier for this FoldTree,
566  // permitting efficient comparison between a pair of FoldTrees
567  size_t hash_value() const;
568 
569  /// @brief Returns the number of residues in the FoldTree
570  ///
571  /// example(s):
572  /// ft.nres()
573  /// See also:
574  /// FoldTree
575  /// FoldTree.check_fold_tree
576  /// FoldTree.num_jump
577  /// FoldTree.simple_tree
578  /// FoldTree.size
579  inline Size nres() const;
580 
581  /// @brief Returns the number of jumps in the FoldTree
582  ///
583  /// example(s):
584  /// ft.num_jump()
585  /// See also:
586  /// FoldTree
587  /// FoldTree.check_fold_tree
588  /// FoldTree.jump_edge
589  /// FoldTree.new_jump
590  /// FoldTree.nres
591  inline Size num_jump() const;
592 
593  /// @brief starting or stopping residue of a jump edge
594  int jump_point( int const lower_higher, int const jump_number ) const;
595 
596  /// @brief Returns true if <seqpos> is a starting or stopping residue of a jump edge
597  ///
598  /// example(s):
599  /// ft.is_jump_point()
600  /// See also:
601  /// FoldTree
602  /// FoldTree.is_cutpoint
603  /// FoldTree.new_jump
604  /// FoldTree.num_jump
605  inline bool is_jump_point( int const seqpos ) const;
606 
607  /// @brief Returns the cutpoint position of jump number <cut>
608  ///
609  /// example(s):
610  /// ft.cutpoint(1)
611  /// See also:
612  /// FoldTree
613  /// FoldTree.jump_edge
614  /// FoldTree.is_cutpoint
615  /// FoldTree.is_jump_point
616  /// FoldTree.num_cutpoint
617  /// FoldTree.num_jump
618  inline int cutpoint( int const cut ) const;
619 
620  /// @brief Returns the number of cutpoints in the FoldTree
621  ///
622  /// example(s):
623  /// ft.num_cutpoint()
624  /// See also:
625  /// FoldTree
626  /// FoldTree.cutpoint
627  /// FoldTree.is_cutpoint
628  /// FoldTree.nres
629  /// FoldTree.num_jump
630  inline int num_cutpoint() const;
631 
632  /// @brief Returns true is position <seqpos> is a cutpoint
633  ///
634  /// example(s):
635  /// ft.is_cutpoint(37)
636  /// See also:
637  /// FoldTree
638  /// FoldTree.cutpoint
639  /// FoldTree.new_jump
640  /// FoldTree.nres
641  /// FoldTree.num_cutpoint
642  /// FoldTree.num_jump
643  inline bool is_cutpoint( int const seqpos ) const;
644 
645  /// @brief cutpoint number for this residue
646  inline int cutpoint_map( int const seqpos ) const;
647 
648  /// @brief Returns the jump edge with jump number <jump_number> (const)
649  ///
650  /// example(s):
651  /// ft.jump_edge(1)
652  /// See also:
653  /// FoldTree
654  /// FoldTree.new_jump
655  /// FoldTree.num_jump
656  Edge const & jump_edge( int const jump_number ) const;
657 
658  /// @brief Returns the jump edge with jump number <jump_number> (non-const)
659  Edge & jump_edge( int const jump_number );
660 
661  /// @brief get the jump_nr connected to jump upstream->downstream, returns 0 if not found
662  inline core::Size jump_nr( core::Size upstream_res, core::Size downstream_res ) const;
663 
664 
665 
666  /// @brief Returns true if the FoldTree is empty
667  ///
668  /// example(s):
669  /// ft.empty()
670  /// See also:
671  /// FoldTree
672  /// FoldTree.check_fold_tree
673  /// FoldTree.clear
674  /// FoldTree.nres
675  /// FoldTree.simple_tree
676  /// FoldTree.size
677  inline
678  bool
679  empty() const
680  {
681  return edge_list_.empty();
682  }
683 
684 
685  /// @brief Returns true if <seqpos> the the root
686  ///
687  /// example(s):
688  /// ft.empty()
689  /// See also:
690  /// FoldTree
691  /// FoldTree.is_cutpoint
692  /// FoldTree.is_jump_point
693  /// FoldTree.nres
694  inline
695  bool
696  is_root( int const seqpos ) const
697  {
698  return ( !edge_list_.empty() && seqpos == begin()->start() );
699  }
700 
701 
702  /// @brief Returns the root vertex position of the FoldTree
703  ///
704  /// example(s):
705  /// ft.empty()
706  /// See also:
707  /// FoldTree
708  /// FoldTree.is_root
709  /// FoldTree.clear
710  /// FoldTree.simple_tree
711  inline
712  int
713  root() const
714  {
715  assert( !empty() );
716  return edge_list_.begin()->start();
717  }
718 
719 
720  /// @brief Return true if a jump exists between <pos1> and <pos2>
721  ///
722  /// example(s):
723  /// ft.empty()
724  /// See also:
725  /// FoldTree
726  /// FoldTree.check_fold_tree
727  /// FoldTree.jump_edge
728  /// FoldTree.new_jump
729  /// FoldTree.nres
730  inline
731  bool
732  jump_exists( int const pos1, int const pos2 ) const
733  {
734  for ( int i=1; i<= static_cast<int>( num_jump()); ++i ) {
735  if ( ( ( pos1 == jump_point(1,i) && pos2 == jump_point(2,i) ) ||
736  ( pos1 == jump_point(2,i) && pos2 == jump_point(1,i) ) ) ) return true;
737  }
738  return false;
739  }
740 
741 
742 
743  // // old stuff -- still used? yeah abinitio mode- endbias check
744  //inline ObjexxFCL::FArray1D_int const & get_jump_edge_count() const;
746  Size const begin_res,
747  Size const size,
748  Size & min_edge_count_out
749  ) const;
750 
751  // more routines for getting derived data
752  // slow: creates vector each time, just for convenience
753  /// @brief get all cutpoints
755  cutpoints() const;
756 
757  /// @brief equal to operator
758  friend
759  bool
760  operator==(
761  FoldTree const & a,
762  FoldTree const & b
763  );
764 
765  /// @brief Not equal to operator
766  friend bool operator!=(const FoldTree& a, const FoldTree& b);
767 
768  /// @brief Slide a polymer cutpoint from one location to another
769  void
770  slide_cutpoint( Size const current_cut, Size const target_cut );
771 
772  /// @brief change an existing jump to start and end in new positions
773  void
774  slide_jump( Size const jump_number, Size const new_res1, Size const new_res2 );
775 
776  /// @brief Useful for removing a loop modeling jump+cut
777  void
779  int jump_begin,
780  int jump_end
781  );
782 
783  /// @brief Useful for removing a loop modeling jump+cut
784  void
786  int const jump_number
787  );
788 
789  /////////////////////////////////////////////////////////////////////////////
790  /////////////////////////////////////////////////////////////////////////////
791  // private methods
792  /////////////////////////////////////////////////////////////////////////////
793  /////////////////////////////////////////////////////////////////////////////
794 
795 private:
796 
797  /// @brief delete a polymer residue (non-jump,non-root)
798  void
799  delete_seqpos_simple( int const seqpos );
800 
801  /// @brief delete a root/jump_point residue
802  void
803  delete_jump_seqpos( int const seqpos );
804 
805 
806  /// @brief non-const begin iterator of edge_list
807  inline
808  iterator
810  {
811  return edge_list_.begin();
812  }
813 
814  /// @brief non-const end iterator of edge_list
815  inline
816  iterator
817  end()
818  {
819  return edge_list_.end();
820  }
821 
822  /// @brief Helper function
823  void
824  add_vertex( int const v );
825 
826  ///////////////////////////// internal book-keeping /////////////
827  // maintain things that depend on both topology and/or order
828  /// @brief update fold tree topology (when edges are changed) if necessary
829  inline bool check_topology() const;
830  /// @brief update fold tree order (when edges are same but the order in the edge_list is changed) if necessary
831  inline bool check_order() const;
832  // private methods for updating derived data
833  /// @brief update total number residues in the fold tree
834  void update_nres() const;
835  /// @brief update number of jumps in the fold tree
836  void update_num_jump() const;
837  /// @brief update jump residues list
838  void update_jump_points() const;
839  /// @brief update the index of jump edges in the edge list
840  void update_jump_edge() const;
841  /// @brief update cutpoints info in the fold tree
842  void update_cutpoints() const;
843  /// @brief update edge counts info
844  void setup_edge_counts() const;
845 
846 
847  // private edge_list_ modifiers
848  /// @brief update edge labels based on whether edges are separating or not.
849  void update_edge_labels();
850 
851  /// @brief helper function to try cutting an edge in a tree.
852  bool cut_edge( int const cut_point );
853 
854  /// @brief cut an edge randomly based on probability without disconnecting fold tree
855  bool
857  ObjexxFCL::FArray1D_float const & cut_bias_sum,
858  int const nres_in
859  );
860 
861 #ifdef USEBOOSTSERIALIZE
862  friend class boost::serialization::access;
863 
864  template<class Archive>
865  void serialize(Archive & ar, const unsigned int version) {
866  ar & edge_list_;
867  ar & new_topology;
868  ar & new_order;
869  ar & nres_;
870  ar & num_jump_;
871  ar & num_cutpoint_;
872  ar & min_edge_count;
873  ar & jump_point_;
874  ar & is_jump_point_;
875  ar & cutpoint_;
876  ar & cutpoint_map_;
877  //ar & is_cutpoint_;
878  update_cutpoints(); // this is because I feel like serializing is_cutpoint_
879  // this also overwrites cutpoint_ and cutpoint_map_ but whatever
880  ar & jump_edge_;
881  ar & edge_count;
882  ar & jump_edge_count;
883  }
884 
885 #endif
886 
887  /////////////////////////////////////////////////////////////////////////////
888  /////////////////////////////////////////////////////////////////////////////
889  // data
890  /////////////////////////////////////////////////////////////////////////////
891  /////////////////////////////////////////////////////////////////////////////
892 
893 
894  /// the list of edges.
895  ///@note vector for fast traversal, but re-ordering, deleting are slow.
897 
898  // book-keeping, so we know when to update derived data
899  /// @brief edges in the edge_list_ have been changed.
900  mutable bool new_topology;
901  /// @brief edges in the edge_list_ have been reorderd.
902  mutable bool new_order;
903 
904  // some derived data ////////////////////////////////////////
905  // you dont need to worry about setting any derived data, they are all
906  // calculated as needed from the fold_tree.
907  // accessed by get_XXX where XXX is the data name
908  // note that these are MUTABLE so they can be synced with the
909  // edge_list_ on the fly inside "const" access methods
910  //
911 
912  /// @brief just the largest vertex in edge_list_
913  mutable int nres_;
914  /// @brief number of jump edges (edges in edge_list_ with label>0)
915  mutable int num_jump_;
916  /// @brief number of cutpoints in the fold tree.
917  /// @note number_cutpoint_ == num_jump_ (if a connected tree)
918  mutable int num_cutpoint_;
919  /// @brief jump number to jump residue number. dimensioned as (2,num_jump_)
921  /// @brief whehter a residue is a jump_point, dimensioned as nres_
923  /// @brief cutpoint number to cutpoint residue number, dimesioned as num_cutpoint_.
925  /// @brief residue number of cutpoint number, 0 if it is not a cutpoint. dimensioned as nres_.
927  /// @brief whether a residue is a cutpoint, dimensioned as nres_
928  mutable ObjexxFCL::FArray1D_bool is_cutpoint_; // nres
929  /// @brief jump number to edge index number in the edge_list_, dimensioned as num_jump_.
931  /// @brief dimensioned as nres_, see setup_edge_counts for more info
933  /// @brief the minimum number in edge_count and jump_edge_count.
934  mutable int min_edge_count;
935  /// @brief dimensioned as num_jump, see setup_edge_counts for more info
937  //mutable std::map< int, std::pair< int, int > > jump_atoms;
938 
939  // @brief computes fixed-size identifier for a string input
940  boost::hash<std::string> hasher;
941 }; // FoldTree
942 
943 
944 
945 ///////////////////////////////////////////////////////////////////////////////
946 /// @brief check_topology and check_order handle the updating of data that depends on
947 /// tree topology and/or tree order.
948 /// @details any routine that depends on the stored derived data (eg any of the access
949 /// methods ) should call check_topology() or check_order() at the beginning.
950 /// @note also, any method function that changes the tree topology or order should set
951 /// the private data members new_topology and/or new_topology to true.
952 ///
953 
954 inline
955 bool
957 {
958  if ( !new_topology ) return false;
959  new_topology = false;
960  new_order = true;
961 
962  // insert updating calls here: ///////////////////////////
963  update_nres();
964  update_num_jump();
968  //////////////////////////////////////////////////////////
969  return true;
970 }
971 
972 // returns true if order has changed
973 /// see details for check_topology
974 inline
975 bool
977 {
978  check_topology();
979  if ( !new_order ) return false;
980  new_order = false;
981 
982  // insert updating calls here: ///////////////////////////
983  //////////////////////////////////////////////////////////
985 
986  //////////////////////////////////////////////////////////
987  return true;
988 }
989 
990 
991 ///////////////////////////////////////////////////////////////////////////////
992 ///@brief routines for retrieving the derived data
993 /// will call check_topology and/or check_order first
994 
995 inline
996 Size
998 {
999  check_topology();
1000  return nres_;
1001 }
1002 
1003 ///////////////////////////////////////////////////////////////////////////////
1004 inline
1005 Size
1007 {
1008  check_topology();
1009  return num_jump_;
1010 }
1011 
1012 
1013 ///////////////////////////////////////////////////////////////////////////////
1014 // is seqpos a jump-point?
1015 inline
1016 bool
1017 FoldTree::is_jump_point( int const seqpos ) const
1018 {
1019  check_topology();
1020  return is_jump_point_[seqpos];
1021 }
1022 
1023 
1024 ///////////////////////////////////////////////////////////////////////////////
1025 inline
1026 int
1027 FoldTree::cutpoint( int const cut ) const
1028 {
1029  check_topology();
1030  return cutpoint_[cut];
1031 }
1032 
1033 
1034 ///////////////////////////////////////////////////////////////////////////////
1035 // number of cutpoints
1036 inline
1037 int
1039 {
1040  check_topology();
1041  return num_cutpoint_;
1042 }
1043 
1044 /// @brief whether a jump exists between these residues
1045 inline
1046 core::Size
1047 FoldTree::jump_nr( core::Size const pos1, core::Size const pos2 ) const
1048 {
1049  for ( int i=1; i<= static_cast<int>( num_jump()); ++i ) {
1050  if ( ( ( pos1 == (Size)jump_point(1,i) && pos2 == (Size)jump_point(2,i) ) ||
1051  ( pos1 == (Size)jump_point(2,i) && pos2 == (Size)jump_point(1,i) ) ) ) return Size( i );
1052  }
1053  return Size( 0 );
1054 }
1055 
1056 ///////////////////////////////////////////////////////////////////////////////
1057 /// @brief cutpoint_map is the inverse of cutpoint_, ie it assigns each
1058 /// sequence position that is a cutpoint to the cutpoint number
1059 /// associated with that cutpoint (cutpoints are numbered in increasing
1060 /// residue number from the beginning of the chain)
1061 
1062 inline
1063 int
1064 FoldTree::cutpoint_map( int const seqpos ) const
1065 {
1066  check_topology();
1067  // sanity
1068  assert( ( is_cutpoint_(seqpos) && cutpoint_map_[seqpos] > 0 &&
1069  cutpoint_[cutpoint_map_[seqpos]] == seqpos ) ||
1070  ( !is_cutpoint_(seqpos) && cutpoint_map_[seqpos] == 0 ) );
1071  return cutpoint_map_[seqpos];
1072 }
1073 
1074 
1075 ///////////////////////////////////////////////////////////////////////////////
1076 inline
1077 bool
1078 FoldTree::is_cutpoint( int const seqpos ) const
1079 {
1080  check_topology();
1081 
1082  if ( seqpos > 0 && seqpos < nres_ ) {
1083  // 0 and nres count as cutpoints for is_cutpoint but they aren't internal cutpoints
1084  // in the foldtree so they dont appear in cutpoint_map_
1085  assert( ( is_cutpoint_(seqpos) && cutpoint_map_[seqpos] > 0 &&
1086  cutpoint_[cutpoint_map_[seqpos]] == seqpos ) ||
1087  ( !is_cutpoint_(seqpos) && cutpoint_map_[seqpos] == 0 ) );
1088  }
1089  return is_cutpoint_(seqpos);
1090 }
1091 
1092 } // namespace kinematics
1093 } // namespace core
1094 
1095 
1096 #endif // INCLUDED_core_kinematics_FoldTree_HH