source: tags/arb-6.0.6/DIST/di_foundclusters.hxx

Last change on this file was 10991, checked in by westram, 11 years ago
  • fix struct/class mismatches
File size: 8.2 KB
Line 
1// ================================================================ //
2//                                                                  //
3//   File      : di_foundclusters.hxx                               //
4//   Purpose   : Store results of cluster detection                 //
5//                                                                  //
6//   Coded by Ralf Westram (coder@reallysoft.de) in November 2009   //
7//   Institute of Microbiology (Technical University Munich)        //
8//   http://www.arb-home.de/                                        //
9//                                                                  //
10// ================================================================ //
11
12#ifndef DI_FOUNDCLUSTERS_HXX
13#define DI_FOUNDCLUSTERS_HXX
14
15#ifndef GUI_ALIVIEW_HXX
16#include <gui_aliview.hxx>
17#endif
18#ifndef SMARTPTR_H
19#include <smartptr.h>
20#endif
21
22
23#ifndef _GLIBCXX_SET
24#include <set>
25#endif
26#ifndef _GLIBCXX_MAP
27#include <map>
28#endif
29#ifndef _GLIBCXX_VECTOR
30#include <vector>
31#endif
32#ifndef _GLIBCXX_ALGORITHM
33#include <algorithm>
34#endif
35#ifndef _GLIBCXX_STRING
36#include <string>
37#endif
38#ifndef DBITEM_SET_H
39#include <dbitem_set.h>
40#endif
41
42#define cl_assert(cond) arb_assert(cond)
43
44class  ClusterTree;
45class  ARB_tree_predicate;
46struct ARB_countedTree;
47class  AW_selection_list;
48class  AW_window;
49
50// ---------------------
51//      Cluster
52
53typedef int32_t ID;
54
55enum ClusterOrder {
56    UNSORTED             = 0, 
57    SORT_BY_MEANDIST     = 1,
58    SORT_BY_MIN_BASES    = 2,
59    SORT_BY_CLUSTERSIZE  = 3,
60    SORT_BY_TREEPOSITION = 4,
61    SORT_BY_MIN_DIST     = 5,
62    SORT_BY_MAX_DIST     = 6,
63
64    SORT_REVERSE = 1<<3,                              // bitflag!
65};
66
67class DisplayFormat;
68
69class Cluster : virtual Noncopyable {
70    double min_dist;                                // min. distance between species inside Cluster
71    double max_dist;                                // dito, but max.
72    double mean_dist;                               // dito, but mean
73
74    double min_bases;                               // min bases used for sequence distance
75    double rel_tree_pos;                            // relative position in tree [0.0 .. 1.0]
76
77    GBDATA    *representative;                      // cluster member with lowest mean distance
78    DBItemSet  members;                             // all members (including representative)
79
80    std::string  desc;                              // cluster description
81    std::string *next_desc;                         // proposed new description (call accept_proposed() to accept it)
82
83    ID id;                                          // unique id for this cluster (used in AWAR_CLUSTER_SELECTED)
84
85    static ID unused_id;
86
87public:
88    Cluster(ClusterTree *ct);
89    ~Cluster() { delete next_desc; }
90
91    ID get_ID() const { return id; }
92
93    size_t get_member_count() const { return members.size(); }
94    void scan_display_widths(DisplayFormat& format) const;
95    const char *get_list_display(const DisplayFormat *format) const;
96
97    const DBItemSet& get_members() const { return members; }
98
99    void mark_all_members(bool mark_representative) const;
100    GBDATA *get_representative() const { return representative; }
101
102    std::string create_description(const ARB_countedTree *ct);
103    std::string get_upgroup_info(const ARB_countedTree *ct, const ARB_tree_predicate& keep_group_name);
104    double get_mean_distance() const { return mean_dist; }
105
106    void propose_description(const std::string& newDesc) {
107        delete next_desc;
108        next_desc = new std::string(newDesc);
109    }
110    void update_description(const ARB_countedTree *ct) {
111        propose_description(create_description(ct));
112    }
113    void accept_proposed(bool accept) {
114        if (accept && next_desc) {
115            desc = *next_desc;
116        }
117
118        delete next_desc;
119        next_desc = NULL;
120    }
121
122private:
123    bool lessByOrder_forward(const Cluster& other, ClusterOrder sortBy) const {
124        bool less = false;
125        switch (sortBy) {
126            case UNSORTED:              break;
127            case SORT_BY_MEANDIST:      less = mean_dist < other.mean_dist; break;
128            case SORT_BY_MIN_BASES:     less = min_bases < other.min_bases; break;
129            case SORT_BY_CLUSTERSIZE:   less = members.size() < other.members.size(); break;
130            case SORT_BY_TREEPOSITION:  less = rel_tree_pos < other.rel_tree_pos;  break;
131            case SORT_BY_MIN_DIST:      less = min_dist < other.min_dist; break;
132            case SORT_BY_MAX_DIST:      less = max_dist < other.max_dist; break;
133               
134            case SORT_REVERSE:
135                cl_assert(0);
136                break;
137        }
138        return less;
139    }
140public:
141    bool lessByOrder(const Cluster& other, ClusterOrder sortBy) const {
142        bool less;
143        if (sortBy&SORT_REVERSE) {
144            less = other.lessByOrder_forward(*this, ClusterOrder(sortBy^SORT_REVERSE));
145        }
146        else {
147            less = lessByOrder_forward(other, sortBy);
148        }
149        return less;
150    }
151
152};
153
154typedef SmartPtr<Cluster>             ClusterPtr;
155typedef std::map<ID, ClusterPtr>      KnownClusters;
156typedef KnownClusters::const_iterator KnownClustersIter;
157typedef std::vector<ID>               ClusterIDs;
158typedef ClusterIDs::const_iterator    ClusterIDsIter;
159
160// --------------------
161//      global data
162
163enum ClusterSubset {
164    STORED_CLUSTERS,
165    SHOWN_CLUSTERS,
166};
167
168struct ClustersData : virtual Noncopyable {
169    WeightedFilter    &weighted_filter;
170    AW_selection_list *clusterList;
171    KnownClusters      known_clusters;              // contains all known clusters
172    ClusterIDs         shown;                       // clusters shown in selection list
173    ClusterIDs         stored;                      // stored clusters
174    ClusterOrder       criteria[2];                 // order of 'shown'
175    bool               sort_needed;                 // need to sort 'shown'
176
177    ClusterIDs& get_subset(ClusterSubset subset) {
178        if (subset == SHOWN_CLUSTERS) {
179            // @@@ sort here if needed
180            return shown;
181        }
182        return stored;
183    }
184    ID idAtPos(int pos, ClusterSubset subset) {
185        ClusterIDs& ids = get_subset(subset);
186        return size_t(pos)<ids.size() ? ids.at(pos) : 0;
187    }
188
189public:
190
191    ClustersData(WeightedFilter& weighted_filter_)
192        : weighted_filter(weighted_filter_)
193        , clusterList(0)
194        , sort_needed(true)
195    {
196        criteria[0] = SORT_BY_MEANDIST;
197        criteria[1] = UNSORTED;
198    }
199
200    void changeSortOrder(ClusterOrder newOrder) {
201        if (newOrder == SORT_REVERSE) { // toggle reverse
202            criteria[0] = ClusterOrder(criteria[0]^SORT_REVERSE);
203        }
204        else if (newOrder != criteria[0]) {
205            criteria[1] = criteria[0];
206            criteria[0] = newOrder;
207        }
208        sort_needed  = true;
209    }
210
211    ClusterPtr clusterWithID(ID id) const {
212        KnownClustersIter found = known_clusters.find(id);
213        return found == known_clusters.end() ? ClusterPtr() : found->second;
214    }
215
216    ClusterPtr clusterAtPos(int pos, ClusterSubset subset) { return clusterWithID(idAtPos(pos, subset)); }
217    size_t count(ClusterSubset subset) { return get_subset(subset).size(); }
218    const ClusterIDs& get_clusterIDs(ClusterSubset subset) { return get_subset(subset); }
219
220    int get_pos(ID id, ClusterSubset subset) {
221        // returns -1 of not member of subset
222        ClusterIDs&     ids   = get_subset(subset);
223        ClusterIDsIter  begin = ids.begin();
224        ClusterIDsIter  end   = ids.end();
225        ClusterIDsIter  found = find(begin, end, id);
226
227        return found == end ? -1 : distance(begin, found);
228    }
229    int get_pos(ClusterPtr cluster, ClusterSubset subset) { return get_pos(cluster->get_ID(), subset); }
230
231    void add(ClusterPtr clus, ClusterSubset subset);
232    void remove(ClusterPtr clus, ClusterSubset subset);
233    void clear(ClusterSubset subset);
234
235    void store(ID id);
236
237    void store_all();
238    void restore_all();
239    void swap_all();
240
241    void update_cluster_selection_list();
242
243    GBDATA *get_gb_main() const { return weighted_filter.get_gb_main(); }
244    AW_root *get_aw_root() const { return weighted_filter.get_aw_root(); }
245
246    void free();
247};
248
249char *originalGroupName(const char *groupname);
250
251#else
252#error di_foundclusters.hxx included twice
253#endif // DI_FOUNDCLUSTERS_HXX
Note: See TracBrowser for help on using the repository browser.