root/trunk/DIST/di_clustertree.hxx

Revision 7917, 6.8 KB (checked in by westram, 9 months ago)
  • cluster-name suffix now configurable
    • show example name for selected cluster
    • help file updated
  • cleaned up all those "name"-functions
    • changed names to make different tasks clear
  • fixed alignment of cluster list formatting (wrong for small float values)
  • ENTER in max.dist or clustersize starts calculation
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : di_clustertree.hxx                                //
4//   Purpose   : Tree structure used for cluster detection         //
5//                                                                 //
6//   Coded by Ralf Westram (coder@reallysoft.de) in October 2009   //
7//   Institute of Microbiology (Technical University Munich)       //
8//   http://www.arb-home.de/                                       //
9//                                                                 //
10// =============================================================== //
11
12#ifndef DI_CLUSTERTREE_HXX
13#define DI_CLUSTERTREE_HXX
14
15#ifndef ARB_TREE_HXX
16#include <ARB_Tree.hxx>
17#endif
18#ifndef AP_SEQUENCE_HXX
19#include <AP_sequence.hxx>
20#endif
21
22#ifndef _GLIBCXX_CLIMITS
23#include <climits>
24#endif
25#ifndef _GLIBCXX_STRING
26#include <string>
27#endif
28#ifndef _GLIBCXX_MAP
29#include <map>
30#endif
31
32
33#define cl_assert(cond) arb_assert(cond)
34
35class AP_sequence;
36class ClusterTree;
37class arb_progress;
38
39enum ClusterState {
40    CS_UNKNOWN       = 0,                           // initial state
41    CS_TOO_SMALL     = 1,                           // cluster is too small
42    CS_MAYBE_CLUSTER = 2,                           // need to test whether this is a cluster
43    CS_NO_CLUSTER    = 4,                           // not a cluster (only worstKnownDistance is known)
44    CS_IS_CLUSTER    = 8,                           // subtree is cluster (all sequence distances are known)
45    CS_SUB_CLUSTER   = 16,                          // like CS_IS_CLUSTER, but father is cluster as well
46};
47
48const float NO_DISTANCE = -1.0;
49
50// ------------------------
51//      ClusterTreeRoot
52
53class ClusterTreeRoot : public ARB_tree_root {
54    AP_FLOAT maxDistance;                           // max. allowed distance inside cluster
55    size_t   minClusterSize;                        // min. size of cluster (number of leafs)
56
57public:
58    ClusterTreeRoot(AliView *aliview, AP_sequence *seqTemplate_, AP_FLOAT maxDistance_, size_t minClusterSize_);
59    virtual ~ClusterTreeRoot();
60
61    ClusterTree *get_root_node() { return DOWNCAST(ClusterTree*, ARB_tree_root::get_root_node()); }
62
63    GB_ERROR find_clusters();
64    size_t get_minClusterSize() const { return minClusterSize; }
65    AP_FLOAT get_maxDistance() const { return maxDistance; }
66};
67
68// ------------------
69//      LeafPairs
70
71class TwoLeafs {
72    ClusterTree *ct1, *ct2; // ct1<ct2!
73
74public:
75    TwoLeafs(ClusterTree *c1, ClusterTree *c2)
76        : ct1(c1<c2 ? c1 : c2)
77        , ct2(c1<c2 ? c2 : c1)
78    {}
79
80    const ClusterTree *first() const { return ct1; }
81    ClusterTree *first() { return ct1; }
82    const ClusterTree *second() const { return ct2; }
83    ClusterTree *second()  { return ct2; }
84
85    bool operator<(const TwoLeafs& other) const {
86        return ct1 == other.ct1 ? ct2<other.ct2 : ct1<other.ct1;
87    }
88};
89
90class LeafRelation {
91    const TwoLeafs *pair;
92    const AP_FLOAT  value;
93public:
94    LeafRelation(const TwoLeafs& pair_, AP_FLOAT value_)
95        : pair(&pair_)
96        , value(value_)
97    {}
98
99    bool operator<(const LeafRelation& other) const {
100        if (value == other.value) return *pair < *other.pair;
101        return value < other.value;
102    }
103
104    const TwoLeafs& get_pair() const  { return *pair; }
105    AP_FLOAT get_value() const { return value; }
106};
107
108typedef std::map<ClusterTree*, AP_FLOAT> NodeValues;
109typedef std::map<TwoLeafs, AP_FLOAT>     LeafRelations;
110typedef LeafRelations::const_iterator    LeafRelationCIter;
111
112// --------------------
113//      ClusterTree
114
115
116#if defined(DEBUG)
117#define TRACE_DIST_CALC
118#endif // DEBUG
119
120class ClusterTree : public ARB_countedTree { // derived from a Noncopyable
121    ClusterState state;
122
123    size_t   leaf_count;                            // number of leafs in subtree
124    size_t   clus_count;                            // number of clusters at and in subtree
125    size_t   depth;                                 // depth of node ( 1 == root )
126    AP_FLOAT min_bases;                             // min. bases used for comparing two members
127
128    NodeValues    *branchDepths;                    // leaf-depths (distance from this each leaf)
129    LeafRelations *branchDists;                     // distance (branch) between two leafs
130    LeafRelations *sequenceDists;                   // real distance between sequences of two leafs
131
132    TwoLeafs *worstKnownDistance;
133
134    void calc_branch_depths();
135    void calc_branch_dists();
136
137#if defined(TRACE_DIST_CALC)
138    size_t calculatedDistances;
139#endif // TRACE_DIST_CALC
140
141public:
142    ClusterTree(ClusterTreeRoot *tree_root_)
143        : ARB_countedTree(tree_root_)
144        , state(CS_UNKNOWN)
145        , leaf_count(0)
146        , clus_count(0)
147        , depth(0)
148        , min_bases(-1.0)
149        , branchDepths(NULL)
150        , branchDists(NULL)
151        , sequenceDists(NULL)
152        , worstKnownDistance(NULL)
153    {}
154
155    virtual ~ClusterTree() {
156        delete worstKnownDistance;
157        delete sequenceDists;
158        delete branchDists;
159        delete branchDepths;
160    }
161    DEFINE_TREE_ACCESSORS(ClusterTreeRoot, ClusterTree);
162
163    virtual ClusterTree *dup() const {              // create new ClusterTree element from prototype
164        return new ClusterTree(const_cast<ClusterTreeRoot*>(get_tree_root()));
165    }
166
167    size_t get_cluster_count() const { return clus_count; }
168    size_t get_leaf_count() const { return leaf_count; }
169    size_t get_depth() const { return depth; }
170
171#if defined(TRACE_DIST_CALC)
172    size_t get_calculated_distances() const { return calculatedDistances; }
173#endif // TRACE_DIST_CALC
174
175    bool knows_seqDists() const { return state & (CS_IS_CLUSTER|CS_SUB_CLUSTER); }
176
177    size_t possible_relations() const { return (leaf_count*(leaf_count-1)) / 2; }
178    size_t known_seqDists() const { return knows_seqDists() ? possible_relations() : 0; }
179
180    ClusterTree *get_cluster(size_t num);           // this allows sequentiell access to clusters
181    ClusterState get_state() const { return state; }
182
183    void init_tree();
184    void detect_clusters(arb_progress& progress);
185
186    const NodeValues *get_branch_depths() {
187        if (!branchDepths) calc_branch_depths();
188        return branchDepths;
189    }
190
191    const LeafRelations *get_branch_dists() {
192        if (!branchDists) calc_branch_dists();
193        return branchDists;
194    }
195
196    const LeafRelations *get_sequence_dists() const { return sequenceDists; }
197
198    AP_FLOAT get_seqDist(const TwoLeafs& pair);
199    const AP_FLOAT *has_seqDist(const TwoLeafs& pair) const;
200    const ClusterTree *commonFatherWith(const ClusterTree *other) const;
201
202    AP_FLOAT get_min_bases() const { return min_bases; }
203
204    void oblivion(bool forgetDistances); // forget unneeded data
205};
206
207struct UseAnyTree : public ARB_tree_predicate {
208    bool selects(const ARB_tree&) const { return true; }
209};
210
211#else
212#error di_clustertree.hxx included twice
213#endif // DI_CLUSTERTREE_HXX
Note: See TracBrowser for help on using the browser.