source: trunk/CONSENSUS_TREE/SyncRoot.hxx

Last change on this file was 18634, checked in by westram, 4 years ago
File size: 6.4 KB
Line 
1// ========================================================= //
2//                                                           //
3//   File      : SyncRoot.hxx                                //
4//   Purpose   : Sync roots of trees                         //
5//                                                           //
6//   Coded by Ralf Westram (coder@reallysoft.de) in May 20   //
7//   http://www.arb-home.de/                                 //
8//                                                           //
9// ========================================================= //
10
11#ifndef SYNCROOT_HXX
12#define SYNCROOT_HXX
13
14#ifndef CT_COMMON_HXX
15#include "CT_common.hxx"
16#endif
17#ifndef _GLIBCXX_VECTOR
18#include <vector>
19#endif
20#ifndef ERRORORTYPE_H
21#include <ErrorOrType.h>
22#endif
23#ifndef MATRIX_H
24#include <matrix.h>
25#endif
26
27typedef SmartPtr<DeconstructedTree> DeconstructedTreePtr;
28
29typedef RefPtr<const SizeAwareTree>     ConstSizeAwareTreePtr;
30typedef RefPtr<const DeconstructedTree> ConstDeconstructedTreePtr;
31
32typedef ErrorOr<ConstSizeAwareTreePtr>     ErrorOrSizeAwareTreePtr;
33typedef ErrorOr<ConstDeconstructedTreePtr> ErrorOrDeconstructedTreePtr;
34
35class RootSynchronizer;
36
37typedef std::vector<ConstSizeAwareTreePtr> ConstSizeAwareTreeVector;
38
39class Multiroot {
40    ConstSizeAwareTreeVector      node;
41    mutable symmetric_matrix<int> distance; // pairwise
42
43#if defined(ASSERTION_USED)
44    bool is_valid() const {
45        if (size()<2) return false; // too small
46        for (int i = 0; i<size(); ++i) {
47            if (!node[i]) return false;
48            if (node[i]->is_root_node()) return false;
49        }
50        return true;
51    }
52#endif
53
54    int lazy_eval_distance(const RootSynchronizer& rsync, int i, int j) const;
55
56public:
57    static const int UNKNOWN_DISTANCE = -1;
58
59    Multiroot(const TreeContainer& trees) :
60        node(trees.get_tree_count(), NULp),
61        distance(trees.get_tree_count())
62    {
63        for (int i = 0; i<size(); ++i) {
64            node[i] = trees.get_tree(i)->get_leftson(); // take any son
65            for (int j = 0; j<i; ++j) {
66                distance.set(i, j, UNKNOWN_DISTANCE);
67            }
68        }
69        arb_assert(is_valid());
70    }
71    Multiroot(const Multiroot& other) :
72        node(other.node),
73        distance(other.size())
74    {
75        for (int i = 0; i<size(); ++i) {
76            for (int j = 0; j<i; ++j) {
77                distance.set(i, j, other.distance.get(i, j));
78            }
79        }
80    }
81
82    int size() const { return distance.size(); }
83    int distanceSum(const RootSynchronizer& rsync) const;
84    int distanceToCenterSum(const RootSynchronizer& rsync) const;
85    int singleTreeDistanceSum(const RootSynchronizer& rsync, int idx);
86
87    ConstSizeAwareTreePtr get_node(int idx) const {
88        if (idx<0 || size_t(idx)>=node.size()) {
89            return NULp;
90        }
91        return node[idx];
92    }
93
94    void replace_node(int idx, ConstSizeAwareTreePtr newNode);
95};
96
97typedef SmartPtr<Multiroot>   MultirootPtr;
98typedef ErrorOr<MultirootPtr> ErrorOrMultirootPtr;
99
100class RootSynchronizer : public TreeContainer {
101    ConstStrArray          species_names;
102    SmartPtr<SpeciesSpace> speciesSpacePtr;
103    SmartPtr<TreeParts>    treePartsPtr;
104
105    std::vector<DeconstructedTreePtr> dtree; // all involved trees
106
107    GB_ERROR deconstructTree(int treeIdx, bool provideProgress);
108
109    bool has_deconstructed_tree(int idx) const {
110        return valid_tree_index(idx) && dtree.size()>size_t(idx) && dtree[idx].isSet();
111    }
112
113    MultirootPtr find_better_multiroot(const Multiroot& start, int best_distSum, int best_centerDist, int *movesPerTree, arb_progress *progress = NULp);
114
115public:
116    RootSynchronizer() {}
117
118    int add(SizeAwareTree*& tree, const char *treename) {
119        arb_assert(!deconstructionPhase()); // now its too late to add new trees
120        return TreeContainer::add(tree, treename);
121    }
122    SizeAwareTree *take_tree(int idx) {
123        SizeAwareTree *t = TreeContainer::take_tree(idx);
124        if (deconstructionPhase()) {
125            dtree[idx].setNull();
126        }
127        return t;
128    }
129
130    void beginDeconstructionPhase();
131    bool deconstructionPhase() const {
132        return speciesSpacePtr.isSet();
133    }
134    GB_ERROR deconstruct_all_trees(bool provideProgress);
135    bool allTreesDeconstructed() const {
136        arb_assert(deconstructionPhase());
137        const int treeCount = get_tree_count();
138        for (int t = 0; t<treeCount; ++t) if (!has_deconstructed_tree(t)) return false;
139        return true;
140    }
141
142    ErrorOrSizeAwareTreePtr find_best_root_candidate(int inTree, int accordingToTree, int& best_dist, bool provideProgress); // find root in 'inTree' with best match to root of tree 'accordingToTree'
143
144    MultirootPtr        get_innermost_edges() const;
145    ErrorOrMultirootPtr get_current_roots() const;
146    ErrorOrMultirootPtr find_good_roots_for_trees(const int MAX_DEPTH, arb_progress *progress = NULp);
147
148    // some helper methods (used to port TEST_part_distance to RootSynchronizer):
149    const SpeciesSpace& get_SpeciesSpace() const {
150        arb_assert(deconstructionPhase());
151        return *speciesSpacePtr;
152    }
153    ErrorOrDeconstructedTreePtr get_DeconstructedTree(int treeIdx) {
154        GB_ERROR error = deconstructTree(treeIdx, false); // lazy eval
155        return ErrorOrDeconstructedTreePtr(error, &*dtree[treeIdx]);
156    }
157    const PART *get_tree_PART(int treeIdx) const {
158        arb_assert(deconstructionPhase());
159        return treePartsPtr->get_tree_PART(treeIdx);
160    }
161    const PART *get_edge_PART(int treeIdx, const SizeAwareTree *sonOfEdge) const {
162        arb_assert(allTreesDeconstructed()); // otherwise dtree contains nothing yet
163        arb_assert(valid_tree_index(treeIdx));
164        arb_assert(!sonOfEdge->is_root_node());
165        return dtree[treeIdx]->find_part(sonOfEdge);
166    }
167
168    int calcEdgeDistance(int i1, const SizeAwareTree *n1, int i2, const SizeAwareTree *n2) const;
169    int calcTreeDistance(int i1, int i2) const; // minimal possible distance between (any edges) of two trees
170    int minDistanceSum() const; // sum of pairwise distances between all trees
171
172    static void find_best_matching_PART_in(int& best_dist, int &best_idx, const PART *part, const DeconstructedTree& in, const PART *tree_part, const PART *tree_in, bool provideProgress);
173    static void find_worst_matching_PART_in(int& worst_dist, int &worst_idx, const PART *part, const DeconstructedTree& in, const PART *tree_part, const PART *tree_in);
174};
175
176#else
177#error SyncRoot.hxx included twice
178#endif // SYNCROOT_HXX
Note: See TracBrowser for help on using the repository browser.