source: branches/profile/SL/ARB_TREE/ARB_Tree.hxx

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