source: branches/profile/SL/AP_TREE/AP_Tree.hxx

Last change on this file was 12121, 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: 12.6 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : AP_Tree.hxx                                       //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#ifndef AP_TREE_HXX
12#define AP_TREE_HXX
13
14#define AP_F_LOADED    ((AW_active)1)
15#define AP_F_NLOADED   ((AW_active)2)
16#define AP_F_SEQUENCES ((AW_active)4)
17#define AP_F_MATRIX    ((AW_active)8)
18#define AP_F_TREE      ((AW_active)16)
19#define AP_F_ALL       ((AW_active)-1)
20
21#define GROUPED_SUM 2   // min. no of species in a group which should be drawn as box
22
23#ifndef ARB_TREE_HXX
24#include <ARB_Tree.hxx>
25#endif
26#ifndef AP_SEQUENCE_HXX
27#include <AP_sequence.hxx>
28#endif
29#ifndef AW_COLOR_GROUPS_HXX
30#include <aw_color_groups.hxx>
31#endif
32
33enum {
34    AWT_GC_CURSOR=0,
35    AWT_GC_BRANCH_REMARK,
36    AWT_GC_BOOTSTRAP,
37    AWT_GC_BOOTSTRAP_LIMITED,
38    AWT_GC_GROUPS,
39    AWT_GC_SELECTED,        // == zero mismatches
40    AWT_GC_UNDIFF,
41    AWT_GC_NSELECTED,       // no hit
42    AWT_GC_ZOMBIES,
43
44    // for multiprobecoloring
45
46    AWT_GC_BLACK,   AWT_GC_YELLOW,
47    AWT_GC_RED,     AWT_GC_MAGENTA,
48    AWT_GC_GREEN,   AWT_GC_CYAN,
49    AWT_GC_BLUE,    AWT_GC_WHITE,
50
51    AWT_GC_FIRST_COLOR_GROUP,
52    AWT_GC_MAX = AWT_GC_FIRST_COLOR_GROUP+AW_COLOR_GROUPS
53};
54
55enum AP_STACK_MODE {
56    NOTHING   = 0,                                                      // nothing to buffer in AP_tree node
57    STRUCTURE = 1,                                                      // only structure
58    SEQUENCE  = 2,                                                      // only sequence
59    BOTH      = 3,                                                      // sequence & treestructure is buffered
60    ROOT      = 7                                                       // old root is buffered
61};
62
63enum AP_UPDATE_FLAGS {
64    AP_UPDATE_OK       = 0,
65    AP_UPDATE_RELINKED = -1,
66    AP_UPDATE_RELOADED = 1,
67    AP_UPDATE_ERROR    = 2
68};
69
70enum AP_TREE_SIDE {  // flags zum kennzeichnen von knoten
71    AP_LEFT,
72    AP_RIGHT,
73    AP_FATHER,
74    AP_LEFTSON,
75    AP_RIGHTSON,
76    AP_NONE
77};
78
79enum AWT_RemoveType { // bit flags
80    AWT_REMOVE_MARKED        = GBT_REMOVE_MARKED,
81    AWT_REMOVE_UNMARKED      = GBT_REMOVE_UNMARKED,
82    AWT_REMOVE_ZOMBIES       = GBT_REMOVE_ZOMBIES,
83    AWT_REMOVE_NO_SEQUENCE   = 8,
84    AWT_REMOVE_BUT_DONT_FREE = 16,
85
86    // please keep AWT_RemoveType in sync with GBT_TreeRemoveType
87    // see ../../ARBDB/arbdbt.h@sync_GBT_TreeRemoveType__AWT_RemoveType
88
89    // combined defines:
90    AWT_KEEP_MARKED = AWT_REMOVE_UNMARKED|AWT_REMOVE_ZOMBIES,
91};
92
93struct AP_rates : virtual Noncopyable {
94    AP_FLOAT  *rates;
95    long       rate_len;
96    AP_filter *filter;
97    long       update;
98
99    AP_rates();
100    char *init(AP_filter *fil);
101    char *init(AP_FLOAT * ra, AP_filter *fil);
102    ~AP_rates();
103    void print();
104};
105
106// ---------------------
107//      AP_tree_root
108
109class AP_tree;
110
111typedef void (*AP_rootChangedCb)(void *cd, AP_tree *old, AP_tree *newroot);
112typedef void (*AP_nodeDelCb)(void *cd, AP_tree *del);
113
114class AP_tree_root : public ARB_seqtree_root { // derived from a Noncopyable
115    AP_rootChangedCb  root_changed_cb;
116    void             *root_changed_cd;
117    AP_nodeDelCb      node_deleted_cb;
118    void             *node_deleted_cd;
119
120    GBDATA *gb_species_data;                        // @@@ needed ?
121
122public:
123    GBDATA *gb_tree_gone; // if all leafs have been removed by tree operations, remember 'ARB_seqtree_root::gb_tree' here (see change_root)
124    char   *gone_tree_name; // set to old tree name when gb_tree_gone gets deleted (used for auto-recreation)
125
126    GBDATA   *gb_table_data;
127    long      tree_timer;
128    long      species_timer;
129    long      table_timer;
130    AP_rates *rates;
131
132    AP_tree_root(AliView *aliView, RootedTreeNodeFactory *nodeMaker_, AP_sequence *seq_proto, bool add_delete_callbacks);
133    ~AP_tree_root() OVERRIDE;
134    DEFINE_TREE_ROOT_ACCESSORS(AP_tree_root, AP_tree);
135
136    // ARB_seqtree_root interface
137
138    virtual void change_root(RootedTree *old, RootedTree *newroot) OVERRIDE;
139
140    virtual GB_ERROR loadFromDB(const char *name) OVERRIDE;
141    virtual GB_ERROR saveToDB() OVERRIDE;
142
143    // AP_tree_root interface
144
145    void update_timers();                           // update the timer
146    bool is_tree_updated();
147    bool is_species_updated();
148
149    void inform_about_delete(AP_tree *old);
150
151    void set_root_changed_callback(AP_rootChangedCb cb, void *cd);
152    void set_node_deleted_callback(AP_nodeDelCb cb, void *cd);
153
154    long remove_leafs(AWT_RemoveType awt_remove_type);
155};
156
157namespace tree_defaults {
158    const float SPREAD    = 1.0;
159    const float ANGLE     = 0.0;
160    const char  LINEWIDTH = 0;
161    const float LENGTH    = DEFAULT_BRANCH_LENGTH;
162};
163
164struct AP_tree_members {
165public: // @@@ make members private
166    unsigned int grouped : 1;   // indicates a folded group
167    unsigned int hidden : 1;    // not shown because a father is a folded group
168    unsigned int has_marked_children : 1; // at least one child is marked
169    unsigned int callback_exists : 1;
170    unsigned int gc : 6;        // color
171
172    char left_linewidth; // @@@ it's stupid to store linewidth IN FATHER (also wastes space)
173    char right_linewidth;
174
175    unsigned leaf_sum;   // number of leaf children of this node
176    unsigned view_sum;   // virtual size of node for display ( isgrouped?sqrt(leaf_sum):leaf_sum )
177
178    float max_tree_depth; // max length of path; for drawing triangles
179    float min_tree_depth; // min length of path; for drawing triangle
180    float spread;
181
182    float left_angle;     // @@@ it's stupid to store angles IN FATHER (also wastes space)
183    float right_angle;
184
185    void reset_child_spread() {
186        spread = tree_defaults::SPREAD;
187    }
188    void reset_both_child_angles() {
189        left_angle  = tree_defaults::ANGLE;
190        right_angle = tree_defaults::ANGLE;
191    }
192    void reset_both_child_linewidths() {
193        left_linewidth  = tree_defaults::LINEWIDTH;
194        right_linewidth = tree_defaults::LINEWIDTH;
195    }
196    void reset_child_layout() {
197        reset_child_spread();
198        reset_both_child_angles();
199        reset_both_child_linewidths();
200    }
201
202    void clear() {
203        reset_child_layout();
204
205        grouped             = 0;
206        hidden              = 0;
207        has_marked_children = 0;
208        callback_exists     = 0;
209        gc                  = 0;
210        leaf_sum            = 0;
211        view_sum            = 0;
212        max_tree_depth      = 0;
213        min_tree_depth      = 0;
214    }
215
216    void swap_son_layout() {
217        std::swap(left_linewidth, right_linewidth);
218
219        // angles need to change orientation when swapped
220        // (they are relative angles, i.e. represent the difference to the default-angle)
221        float org_left = left_angle;
222        left_angle     = -right_angle;
223        right_angle    = -org_left;
224    }
225};
226
227struct AP_branch_members {
228public:
229    unsigned int touched : 1;       // nni and kl
230
231    void clear() {
232        touched = 0;
233    }
234};
235
236class AP_tree : public ARB_seqtree {
237public: // @@@ fix public members
238    AP_tree_members   gr;
239    AP_branch_members br;
240
241    unsigned long stack_level; // @@@ maybe can be moved to AP_tree_nlen
242
243    // ------------------
244    //      functions
245private:
246    void load_node_info();    // load linewidth etc from DB
247
248    char& linewidth_ref() {
249        AP_tree_members& tm = get_father()->gr;
250        return is_leftson() ? tm.left_linewidth : tm.right_linewidth;
251    }
252    const char& linewidth_ref() const { return const_cast<AP_tree*>(this)->linewidth_ref(); }
253
254    float& angle_ref() {
255        AP_tree_members& tm = get_father()->gr;
256        return is_leftson() ? tm.left_angle : tm.right_angle;
257    }
258    const float& angle_ref() const { return const_cast<AP_tree*>(this)->angle_ref(); }
259
260    static inline int force_legal_width(int width) { return width<0 ? 0 : (width>128 ? 128 : width); }
261
262    void buildLeafList_rek(AP_tree **list, long& num);
263    void buildNodeList_rek(AP_tree **list, long& num);
264    void buildBranchList_rek(AP_tree **list, long& num, bool create_terminal_branches, int deep);
265
266    const AP_tree *flag_branch() const { return get_father()->get_father() ? this : get_father()->get_leftson(); }
267
268    void reset_child_angles();
269    void reset_child_linewidths();
270    void reset_child_layout();
271
272    void update_subtree_information();
273
274public:
275    explicit AP_tree(AP_tree_root *troot)
276        : ARB_seqtree(troot),
277          stack_level(0)
278    {
279        gr.clear();
280        br.clear();
281    }
282    ~AP_tree() OVERRIDE;
283
284    DEFINE_TREE_ACCESSORS(AP_tree_root, AP_tree);
285
286    void compute_tree() OVERRIDE;
287
288    unsigned count_leafs() const;
289    unsigned get_leaf_count() const OVERRIDE { // assumes compute_tree has been called (since last tree modification)
290        return gr.leaf_sum;
291    }
292
293
294    void load_subtree_info(); // recursive load_node_info (no need to call, called by loadFromDB)
295
296    int colorize(GB_HASH *hashptr);  // function for coloring the tree; ak
297    void uncolorize() { compute_tree(); }
298
299    virtual void insert(AP_tree *new_brother);
300    virtual void initial_insert(AP_tree *new_brother, AP_tree_root *troot);
301    virtual void remove();                          // remove this+father (but do not delete)
302    virtual void swap_assymetric(AP_TREE_SIDE mode); // 0 = AP_LEFT_son  1=AP_RIGHT_son
303
304    void swap_sons() OVERRIDE {
305        rt_assert(!is_leaf); // @@@ if never fails -> remove condition below
306        if (!is_leaf) {
307            ARB_seqtree::swap_sons();
308            gr.swap_son_layout();
309        }
310    }
311
312    GB_ERROR cantMoveNextTo(AP_tree *new_brother);  // use this to detect impossible moves
313    virtual void moveNextTo(AP_tree *new_brother, AP_FLOAT rel_pos); // move to new brother
314
315    void set_root() OVERRIDE;
316
317    GB_ERROR tree_write_tree_rek(GBDATA *gb_tree);
318    GB_ERROR relink() __ATTR__USERESULT; // @@@ used ? if yes -> move to AP_tree_root or ARB_seqtree_root
319
320    virtual AP_UPDATE_FLAGS check_update();
321
322    void update();
323
324    int get_linewidth() const { return is_root_node() ? 0 : linewidth_ref(); }
325    void set_linewidth(int width) { if (father) linewidth_ref() = force_legal_width(width); }
326    void reset_linewidth() { set_linewidth(tree_defaults::LINEWIDTH); }
327    void set_linewidth_recursive(int width);
328
329    float get_angle() const { return is_root_node() ? 0.0 : angle_ref(); }
330    void set_angle(float angle) {
331        if (father) {
332            angle_ref() = angle;
333            if (get_father()->is_root_node()) {
334                // always set angle of other son at root-node
335                // @@@ works wrong if locigal-zoom is active
336                get_brother()->angle_ref() = angle;
337            }
338        }
339    }
340    void reset_angle() { set_angle(tree_defaults::ANGLE); }
341
342    void buildLeafList(AP_tree **&list, long &num); // returns a list of leafs
343    void buildNodeList(AP_tree **&list, long &num); // returns a list of inner nodes (w/o root)
344    void buildBranchList(AP_tree **&list, long &num, bool create_terminal_branches, int deep);
345
346    AP_tree **getRandomNodes(int nnodes); // returns a list of random nodes (no leafs)
347
348    void clear_branch_flags();
349
350    void touch_branch() { const_cast<AP_tree*>(flag_branch())->br.touched = 1; }
351    int get_branch_flag() const { return flag_branch()->br.touched; }
352
353    GB_ERROR move_group_info(AP_tree *new_group) __ATTR__USERESULT;
354    bool is_inside_folded_group() const;
355
356    void mark_duplicates();
357    const char *mark_long_branches(double min_rel_diff, double min_abs_diff);
358    const char *mark_deep_leafs(int min_depth, double min_rootdist);
359    const char *mark_degenerated_branches(double degeneration_factor);
360    const char *analyse_distances();
361
362    void justify_branch_lenghs(GBDATA *gb_main);
363    void relink_tree(GBDATA *gb_main, void (*relinker)(GBDATA *&ref_gb_node, char *&ref_name, GB_HASH *organism_hash), GB_HASH *organism_hash);
364
365    // reset-functions below affect 'this' and childs:
366    void reset_subtree_spreads();
367    void reset_subtree_angles();
368    void reset_subtree_linewidths();
369    void reset_subtree_layout();
370
371    bool hasName(const char *Name) const { return Name && name && Name[0] == name[0] && strcmp(Name, name) == 0; }
372};
373
374struct AP_TreeNodeFactory : public RootedTreeNodeFactory {
375    virtual RootedTree *makeNode(TreeRoot *root) const {
376        return new AP_tree(DOWNCAST(AP_tree_root*, root));
377    }
378};
379
380#else
381#error AP_Tree.hxx included twice
382#endif // AP_TREE_HXX
Note: See TracBrowser for help on using the repository browser.