source: trunk/SL/ARB_TREE/ARB_Tree.hxx

Last change on this file was 17877, checked in by westram, 6 years ago
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.4 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : ARB_Tree.hxx                                      //
4//   Purpose   : Tree types with sequence knowledge                //
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 ARB_TREE_HXX
13#define ARB_TREE_HXX
14
15#ifndef ALIVIEW_HXX
16#include <AliView.hxx>
17#endif
18#ifndef DOWNCAST_H
19#include <downcast.h>
20#endif
21#ifndef TREENODE_H
22#include <TreeNode.h>
23#endif
24#ifndef AP_SEQUENCE_HXX
25#include <AP_sequence.hxx>
26#endif
27
28
29#define at_assert(cond) arb_assert(cond)
30
31typedef void (*ARB_tree_node_del_cb)(GBDATA*, class ARB_seqtree*);
32
33class ARB_seqtree_root;
34class ARB_seqtree;
35class ARB_edge;
36class AP_weights;
37class AliView;
38
39#ifdef GCC_TOO_SMART_FOR_USEFUL_FINAL_TYPE_SUGGESTION
40# pragma GCC diagnostic push
41# pragma GCC diagnostic ignored "-Wsuggest-final-types"
42#endif
43
44class ARB_seqtree_root : public TreeRoot { // derived from Noncopyable
45    AliView     *ali;
46
47    AP_sequence *seqTemplate;
48
49    // following variables are set, if the tree has been loaded from DB
50    char   *tree_name;                              // name of the tree in DB
51    GBDATA *gb_tree;                                // tree container in DB
52
53    bool isLinkedToDB;
54    bool addDeleteCallbacks;
55
56protected:
57    void set_gb_tree(GBDATA *gbTree) {
58        at_assert(implicated(gb_tree, gb_tree == gbTree));
59        at_assert(tree_name);
60        gb_tree = gbTree;
61    }
62    void set_gb_tree_and_name(GBDATA *gbTree, const char *name) {
63        at_assert(!gb_tree);
64        at_assert(!tree_name);
65        gb_tree   = gbTree;
66        tree_name = ARB_strdup(name);
67    }
68
69public:
70    ARB_seqtree_root(AliView *aliView, AP_sequence *seqTempl, bool add_delete_callbacks);
71    ~ARB_seqtree_root() OVERRIDE;
72
73    DEFINE_TREE_ROOT_ACCESSORS(ARB_seqtree_root, ARB_seqtree);
74
75    const AliView *get_aliview() const { return ali; }
76
77    const AP_filter *get_filter() const { return ali->get_filter(); }
78    const AP_weights *get_weights() const { return ali->get_weights(); }
79
80    GBDATA *get_gb_main() const { return ali->get_gb_main(); }
81
82    GBDATA *get_gb_tree() const { return gb_tree; } // NULp if no tree loaded (or tree disappeared from DB)
83    void tree_deleted_cb(GBDATA *gb_tree_del);      // internal
84
85    const char *get_tree_name() const { return tree_name; } // NULp if no tree loaded (or tree disappeared from DB)
86
87    virtual GB_ERROR loadFromDB(const char *name) __ATTR__USERESULT;
88    virtual GB_ERROR saveToDB() __ATTR__USERESULT;
89
90    const AP_sequence *get_seqTemplate() const { return seqTemplate; }
91
92    GB_ERROR linkToDB(int *zombies, int *duplicates) __ATTR__USERESULT;
93    void unlinkFromDB(); // @@@ is (but should not be) unused
94    PREPARE_MARK_NONFINAL_CLASS(ARB_seqtree_root);
95};
96MARK_NONFINAL_CLASS(ARB_seqtree_root); // does not work for too smart gcc|s
97#ifdef GCC_TOO_SMART_FOR_USEFUL_FINAL_TYPE_SUGGESTION
98# pragma GCC diagnostic pop
99#endif
100
101MARK_NONFINAL_FUNCTION(ARB_seqtree_root,GB_ERROR,loadFromDB,(const char*),NULp);
102MARK_NONFINAL_FUNCTION(ARB_seqtree_root,GB_ERROR,saveToDB,(),NULp);
103
104struct ARB_tree_info {
105    size_t leafs;
106    size_t innerNodes;
107    size_t groups;
108    size_t unlinked;                                // unlinked leafs (same as 'leafs' if tree is unlinked)
109    size_t marked;                                  // leafs linked to marked species
110    // size_t with_sequence; // @@@ add when AP_sequence is member of ARB_seqtree
111
112    ARB_tree_info();
113
114    size_t nodes()    const { return innerNodes+leafs; }
115    size_t linked()   const { return leafs-unlinked; }
116    size_t unmarked() const { return linked()-marked; }
117};
118
119class ARB_seqtree : public TreeNode { // derived from Noncopyable
120    friend GB_ERROR ARB_seqtree_root::loadFromDB(const char *name);
121    friend GB_ERROR ARB_seqtree_root::linkToDB(int *zombies, int *duplicates);
122    friend void     ARB_seqtree_root::unlinkFromDB();
123
124    AP_sequence *seq; /* NULp if tree is unlinked
125                       * otherwise automatically valid for leafs with gb_node!
126                       * may be set manually for inner nodes
127                       */
128
129    // ------------------
130    //      functions
131
132    void unloadSequences();
133    GB_ERROR preloadLeafSequences();
134
135    GB_ERROR add_delete_cb_rec(ARB_tree_node_del_cb cb) __ATTR__USERESULT;
136    void remove_delete_cb_rec(ARB_tree_node_del_cb cb);
137
138protected:
139    AP_sequence *take_seq() { // afterwards not has no seq and caller is responsible for sequence
140        AP_sequence *result = seq;
141        seq = NULp;
142        return result;
143    }
144    void replace_seq(AP_sequence *sequence);
145
146    ~ARB_seqtree() OVERRIDE;
147
148public:
149    ARB_seqtree(ARB_seqtree_root *root) :
150        TreeNode(root),
151        seq(NULp)
152    {}
153
154    DEFINE_TREE_ACCESSORS(ARB_seqtree_root, ARB_seqtree);
155
156    void calcTreeInfo(ARB_tree_info& info);
157
158    // order in dendogram:
159    bool is_upper_son() const { return is_leftson(); }
160    bool is_lower_son() const { return is_rightson(); }
161
162    AP_sequence *get_seq() { return seq; }
163    const AP_sequence *get_seq() const { return seq; }
164    AP_sequence *set_seq(AP_sequence *sequence) {
165        at_assert(!seq); // already set
166#ifndef UNIT_TESTS // UT_DIFF
167        // unit tests are allowed to leave sequence undefined // @@@ better solution?
168        at_assert(sequence);
169#endif
170        seq = sequence;
171        return seq;
172    }
173
174    bool hasSequence() const { return seq && seq->hasSequence(); }
175
176    void mark_subtree();
177    bool contains_marked_species();
178
179};
180
181#define OVERRIDE_SEQ_ACCESSORS(SEQTYPE,BASETREETYPE)                                                            \
182    SEQTYPE *get_seq() { return DOWNCAST(SEQTYPE*,BASETREETYPE::get_seq()); }                                   \
183    const SEQTYPE *get_seq() const { return DOWNCAST(const SEQTYPE*,BASETREETYPE::get_seq()); }                 \
184    SEQTYPE *set_seq(AP_sequence *sequence) { return DOWNCAST(SEQTYPE*, BASETREETYPE::set_seq(sequence)); }     \
185
186struct ARB_tree_predicate {
187    virtual ~ARB_tree_predicate() {}
188    virtual bool selects(const ARB_seqtree& tree) const = 0;
189};
190
191// ------------------------
192//      ARB_countedTree
193//      tree that knows its size
194
195class ARB_countedTree : public ARB_seqtree {
196protected:
197    ~ARB_countedTree() OVERRIDE {}
198public:
199    explicit ARB_countedTree(ARB_seqtree_root *tree_root_)
200        : ARB_seqtree(tree_root_)
201    {}
202    DEFINE_TREE_ACCESSORS(ARB_seqtree_root, ARB_countedTree);
203
204    // @@@ TODO:
205    // - add debug code (checking init_tree() is called exactly once)
206    // - init_tree() might be called automatically via announce_tree_constructed()
207
208    virtual void init_tree()              = 0;      /* impl. shall initialize the tree
209                                                     * (including some kind of leaf counter)
210                                                     * needs to be called manually */
211
212    void compute_tree() OVERRIDE {} // ARB_countedTree always is informed about its subtrees
213
214    size_t relative_position_in(const ARB_countedTree *upgroup) const;
215};
216
217
218
219#else
220#error ARB_Tree.hxx included twice
221#endif // ARB_TREE_HXX
Note: See TracBrowser for help on using the repository browser.