| 1 | // ============================================================= // |
|---|
| 2 | // // |
|---|
| 3 | // File : CT_ctree.hxx // |
|---|
| 4 | // Purpose : interface to consensus tree calculation // |
|---|
| 5 | // // |
|---|
| 6 | // Institute of Microbiology (Technical University Munich) // |
|---|
| 7 | // http://www.arb-home.de/ // |
|---|
| 8 | // // |
|---|
| 9 | // ============================================================= // |
|---|
| 10 | |
|---|
| 11 | #ifndef CT_CTREE_HXX |
|---|
| 12 | #define CT_CTREE_HXX |
|---|
| 13 | |
|---|
| 14 | #ifndef CT_COMMON_HXX |
|---|
| 15 | #include <CT_common.hxx> |
|---|
| 16 | #endif |
|---|
| 17 | #ifndef ARBTOOLS_H |
|---|
| 18 | #include <arbtools.h> |
|---|
| 19 | #endif |
|---|
| 20 | #ifndef ARBDBT_H |
|---|
| 21 | #include <arbdbt.h> |
|---|
| 22 | #endif |
|---|
| 23 | #ifndef _GLIBCXX_STRING |
|---|
| 24 | #include <string> |
|---|
| 25 | #endif |
|---|
| 26 | |
|---|
| 27 | struct NT_NODE; |
|---|
| 28 | class RB_INFO; |
|---|
| 29 | |
|---|
| 30 | // ----------------------- |
|---|
| 31 | // ConsensusTree |
|---|
| 32 | // |
|---|
| 33 | // (Note: used directly from DIST/DI_matr.cxx) |
|---|
| 34 | |
|---|
| 35 | class ConsensusTree : public SpeciesSpace, public DeconstructedTree { // derived from Noncopyable |
|---|
| 36 | struct RB_INFO *rbtree(const NT_NODE *tree, TreeRoot *root); |
|---|
| 37 | SizeAwareTree *rb_gettree(const NT_NODE *tree); |
|---|
| 38 | |
|---|
| 39 | public: |
|---|
| 40 | ConsensusTree(const CharPtrArray& names_); |
|---|
| 41 | |
|---|
| 42 | __ATTR__USERESULT GB_ERROR insert_tree_weighted(const TreeNode *tree, int leafs, double weight, bool provideProgress); |
|---|
| 43 | |
|---|
| 44 | SizeAwareTree *get_consensus_tree(GB_ERROR& error); |
|---|
| 45 | }; |
|---|
| 46 | |
|---|
| 47 | // ------------------------------ |
|---|
| 48 | // ConsensusTreeBuilder |
|---|
| 49 | |
|---|
| 50 | class ConsensusTreeBuilder : public TreeContainer { |
|---|
| 51 | // wrapper for ConsensusTree |
|---|
| 52 | // - automatically collects species occurring in added trees (has to be done by caller of ConsensusTree) |
|---|
| 53 | // - uses much more memory than using ConsensusTree directly, since it stores all added trees |
|---|
| 54 | // |
|---|
| 55 | // Not helpful for consensing thousands of trees like bootstrapping does |
|---|
| 56 | |
|---|
| 57 | typedef std::vector<double> Weights; |
|---|
| 58 | |
|---|
| 59 | Weights weights; |
|---|
| 60 | |
|---|
| 61 | public: |
|---|
| 62 | void add(SizeAwareTree*& tree, const char *treename, double weight) { |
|---|
| 63 | tree->get_tree_root()->find_innermost_edge().set_root(); // only wanted when building consensus tree |
|---|
| 64 | |
|---|
| 65 | // (currently) reordering trees before deconstructing no longer |
|---|
| 66 | // affects the resulting consense tree (as performed as unit tests). |
|---|
| 67 | // |
|---|
| 68 | // tree->reorder_tree(BIG_BRANCHES_TO_TOP); |
|---|
| 69 | // tree->reorder_tree(BIG_BRANCHES_TO_BOTTOM); |
|---|
| 70 | // tree->reorder_tree(BIG_BRANCHES_TO_EDGE); |
|---|
| 71 | |
|---|
| 72 | TreeContainer::add(tree, treename); |
|---|
| 73 | weights.push_back(weight); |
|---|
| 74 | } |
|---|
| 75 | |
|---|
| 76 | SizeAwareTree *get(size_t& different_species, GB_ERROR& error) { |
|---|
| 77 | arb_assert(!error); |
|---|
| 78 | |
|---|
| 79 | ConstStrArray species_names; |
|---|
| 80 | get_species_names(species_names); |
|---|
| 81 | |
|---|
| 82 | different_species = get_species_count(); |
|---|
| 83 | ConsensusTree ctree(species_names); |
|---|
| 84 | { |
|---|
| 85 | arb_progress deconstruct("deconstructing", get_tree_count()); |
|---|
| 86 | |
|---|
| 87 | for (size_t i = 0; i<get_tree_count() && !error; ++i) { |
|---|
| 88 | const TreeInfo& treeInfo = get_tree_info(i); |
|---|
| 89 | const SizeAwareTree *tree = get_tree(i); |
|---|
| 90 | |
|---|
| 91 | error = ctree.insert_tree_weighted(tree, treeInfo.species_count(), weights[i], true); |
|---|
| 92 | ++deconstruct; |
|---|
| 93 | if (error) { |
|---|
| 94 | error = GBS_global_string("Failed to deconstruct '%s' (Reason: %s)", treeInfo.name(), error); |
|---|
| 95 | } |
|---|
| 96 | else { |
|---|
| 97 | error = deconstruct.error_if_aborted(); |
|---|
| 98 | } |
|---|
| 99 | } |
|---|
| 100 | if (error) deconstruct.done(); |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | if (error) return NULp; |
|---|
| 104 | |
|---|
| 105 | #if defined(DEBUG) |
|---|
| 106 | // if class ConsensusTree does depend on any local data, |
|---|
| 107 | // instanciating another instance will interfere: |
|---|
| 108 | ConsensusTree influence(species_names); |
|---|
| 109 | #endif |
|---|
| 110 | |
|---|
| 111 | arb_progress reconstruct("reconstructing"); |
|---|
| 112 | return ctree.get_consensus_tree(error); |
|---|
| 113 | } |
|---|
| 114 | |
|---|
| 115 | char *get_tree_remark() const; |
|---|
| 116 | }; |
|---|
| 117 | |
|---|
| 118 | |
|---|
| 119 | #else |
|---|
| 120 | #error CT_ctree.hxx included twice |
|---|
| 121 | #endif // CT_CTREE_HXX |
|---|