source: branches/profile/DIST/di_foundclusters.hxx

Last change on this file was 12877, checked in by westram, 5 years ago
File size: 8.4 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
69enum ClusterMarkMode { // what to mark (REP=representative)
70    CMM_ALL_BUT_REP = 0,
71    CMM_ALL         = 1,
72    CMM_ONLY_REP    = 2,
73};
74
75class Cluster : virtual Noncopyable {
76    double min_dist;                                // min. distance between species inside Cluster
77    double max_dist;                                // dito, but max.
78    double mean_dist;                               // dito, but mean
79
80    double min_bases;                               // min bases used for sequence distance
81    double rel_tree_pos;                            // relative position in tree [0.0 .. 1.0]
82
83    GBDATA    *representative;                      // cluster member with lowest mean distance
84    DBItemSet  members;                             // all members (including representative)
85
86    std::string  desc;                              // cluster description
87    std::string *next_desc;                         // proposed new description (call accept_proposed() to accept it)
88
89    ID id;                                          // unique id for this cluster (used in AWAR_CLUSTER_SELECTED)
90
91    static ID unused_id;
92
93public:
94    Cluster(ClusterTree *ct);
95    ~Cluster() { delete next_desc; }
96
97    ID get_ID() const { return id; }
98
99    size_t get_member_count() const { return members.size(); }
100    void scan_display_widths(DisplayFormat& format) const;
101    const char *get_list_display(const DisplayFormat *format) const; // only valid after calling scan_display_widths
102
103    const DBItemSet& get_members() const { return members; }
104
105    void mark_all_members(ClusterMarkMode mmode) const;
106    GBDATA *get_representative() const { return representative; }
107
108    std::string create_description(const ARB_countedTree *ct);
109    std::string get_upgroup_info(const ARB_countedTree *ct, const ARB_tree_predicate& keep_group_name);
110    double get_mean_distance() const { return mean_dist; }
111
112    void propose_description(const std::string& newDesc) {
113        delete next_desc;
114        next_desc = new std::string(newDesc);
115    }
116    void update_description(const ARB_countedTree *ct) {
117        propose_description(create_description(ct));
118    }
119    void accept_proposed(bool accept) {
120        if (accept && next_desc) {
121            desc = *next_desc;
122        }
123
124        delete next_desc;
125        next_desc = NULL;
126    }
127
128private:
129    bool lessByOrder_forward(const Cluster& other, ClusterOrder sortBy) const {
130        bool less = false;
131        switch (sortBy) {
132            case UNSORTED:              break;
133            case SORT_BY_MEANDIST:      less = mean_dist < other.mean_dist; break;
134            case SORT_BY_MIN_BASES:     less = min_bases < other.min_bases; break;
135            case SORT_BY_CLUSTERSIZE:   less = members.size() < other.members.size(); break;
136            case SORT_BY_TREEPOSITION:  less = rel_tree_pos < other.rel_tree_pos;  break;
137            case SORT_BY_MIN_DIST:      less = min_dist < other.min_dist; break;
138            case SORT_BY_MAX_DIST:      less = max_dist < other.max_dist; break;
139               
140            case SORT_REVERSE:
141                cl_assert(0);
142                break;
143        }
144        return less;
145    }
146public:
147    bool lessByOrder(const Cluster& other, ClusterOrder sortBy) const {
148        bool less;
149        if (sortBy&SORT_REVERSE) {
150            less = other.lessByOrder_forward(*this, ClusterOrder(sortBy^SORT_REVERSE));
151        }
152        else {
153            less = lessByOrder_forward(other, sortBy);
154        }
155        return less;
156    }
157
158};
159
160typedef SmartPtr<Cluster>             ClusterPtr;
161typedef std::map<ID, ClusterPtr>      KnownClusters;
162typedef KnownClusters::const_iterator KnownClustersIter;
163typedef std::vector<ID>               ClusterIDs;
164typedef ClusterIDs::const_iterator    ClusterIDsIter;
165
166// --------------------
167//      global data
168
169enum ClusterSubset {
170    STORED_CLUSTERS,
171    SHOWN_CLUSTERS,
172};
173
174struct ClustersData : virtual Noncopyable {
175    WeightedFilter    &weighted_filter;
176    AW_selection_list *clusterList;
177    KnownClusters      known_clusters;              // contains all known clusters
178    ClusterIDs         shown;                       // clusters shown in selection list
179    ClusterIDs         stored;                      // stored clusters
180    ClusterOrder       criteria[2];                 // order of 'shown'
181    bool               sort_needed;                 // need to sort 'shown'
182
183    ClusterIDs& get_subset(ClusterSubset subset) {
184        if (subset == SHOWN_CLUSTERS) {
185            // @@@ sort here if needed
186            return shown;
187        }
188        return stored;
189    }
190    ID idAtPos(int pos, ClusterSubset subset) {
191        ClusterIDs& ids = get_subset(subset);
192        return size_t(pos)<ids.size() ? ids.at(pos) : 0;
193    }
194
195public:
196
197    ClustersData(WeightedFilter& weighted_filter_)
198        : weighted_filter(weighted_filter_)
199        , clusterList(0)
200        , sort_needed(true)
201    {
202        criteria[0] = SORT_BY_MEANDIST;
203        criteria[1] = UNSORTED;
204    }
205
206    void changeSortOrder(ClusterOrder newOrder) {
207        if (newOrder == SORT_REVERSE) { // toggle reverse
208            criteria[0] = ClusterOrder(criteria[0]^SORT_REVERSE);
209        }
210        else if (newOrder != criteria[0]) {
211            criteria[1] = criteria[0];
212            criteria[0] = newOrder;
213        }
214        sort_needed  = true;
215    }
216
217    ClusterPtr clusterWithID(ID id) const {
218        KnownClustersIter found = known_clusters.find(id);
219        return found == known_clusters.end() ? ClusterPtr() : found->second;
220    }
221
222    ClusterPtr clusterAtPos(int pos, ClusterSubset subset) { return clusterWithID(idAtPos(pos, subset)); }
223    size_t count(ClusterSubset subset) { return get_subset(subset).size(); }
224    const ClusterIDs& get_clusterIDs(ClusterSubset subset) { return get_subset(subset); }
225
226    int get_pos(ID id, ClusterSubset subset) {
227        // returns -1 of not member of subset
228        ClusterIDs&     ids   = get_subset(subset);
229        ClusterIDsIter  begin = ids.begin();
230        ClusterIDsIter  end   = ids.end();
231        ClusterIDsIter  found = find(begin, end, id);
232
233        return found == end ? -1 : distance(begin, found);
234    }
235    int get_pos(ClusterPtr cluster, ClusterSubset subset) { return get_pos(cluster->get_ID(), subset); }
236
237    void add(ClusterPtr clus, ClusterSubset subset);
238    void remove(ClusterPtr clus, ClusterSubset subset);
239    void clear(ClusterSubset subset);
240
241    void store(ID id);
242
243    void store_all();
244    void restore_all();
245    void swap_all();
246
247    void update_cluster_selection_list();
248
249    GBDATA *get_gb_main() const { return weighted_filter.get_gb_main(); }
250    AW_root *get_aw_root() const { return weighted_filter.get_aw_root(); }
251
252    void free();
253};
254
255char *originalGroupName(const char *groupname);
256
257#else
258#error di_foundclusters.hxx included twice
259#endif // DI_FOUNDCLUSTERS_HXX
Note: See TracBrowser for help on using the repository browser.