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

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: 52.0 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : AP_Tree.cxx                                       //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#include "AP_Tree.hxx"
12
13#include <AP_filter.hxx>
14#include <awt_attributes.hxx>
15#include <aw_msg.hxx>
16
17#include <math.h>
18#include <map>
19#include <climits>
20#include <arb_progress.h>
21#include <ad_cb.h>
22
23using namespace std;
24
25/*!***************************************************************************************
26 ************           Rates                       **********
27 *****************************************************************************************/
28void AP_rates::print()
29{
30    AP_FLOAT max;
31    int i;
32
33    max = 0.0;
34    for (i=0; i<rate_len; i++) {
35        if (rates[i] > max) max = rates[i];
36    }
37    printf("rates:");
38    for (i=0; i<rate_len; i++) {
39        putchar('0' + (int)(rates[i]/max*9.9));
40    }
41    printf("\n");
42}
43
44AP_rates::AP_rates() {
45    memset ((char *)this, 0, sizeof(AP_rates));
46}
47
48char *AP_rates::init(AP_filter *fil) {
49    if (fil->get_timestamp() <= this->update) return 0;
50
51    rate_len = fil->get_filtered_length();
52    delete [] rates;
53    rates = new AP_FLOAT[rate_len];
54    for (int i=0; i<rate_len; i++) {
55        rates[i] = 1.0;
56    }
57    this->update = fil->get_timestamp();
58    return 0;
59}
60
61char *AP_rates::init(AP_FLOAT * ra, AP_filter *fil)
62{
63    if (fil->get_timestamp() <= this->update) return 0;
64
65    rate_len = fil->get_filtered_length();
66    delete [] rates;
67    rates = new AP_FLOAT[rate_len];
68    int i, j;
69    for (j=i=0; i<rate_len; j++) {
70        if (fil->use_position(j)) {
71            rates[i++] = ra[j];
72        }
73    }
74    this->update = fil->get_timestamp();
75    return 0;
76}
77
78AP_rates::~AP_rates() { delete [] rates; }
79
80
81/*!***************************************************************************************
82 ************           AP_tree_root                    **********
83 *****************************************************************************************/
84
85AP_tree_root::AP_tree_root(AliView *aliView, RootedTreeNodeFactory *nodeMaker_, AP_sequence *seq_proto, bool add_delete_callbacks)
86    : ARB_seqtree_root(aliView, nodeMaker_, seq_proto, add_delete_callbacks),
87      root_changed_cb(NULL), root_changed_cd(NULL),
88      node_deleted_cb(NULL), node_deleted_cd(NULL),
89      gb_tree_gone(NULL),
90      gone_tree_name(NULL),
91      tree_timer(0),
92      species_timer(0),
93      table_timer(0),
94      rates(NULL)
95{
96    GBDATA         *gb_main = get_gb_main();
97    GB_transaction  ta(gb_main);
98
99    gb_species_data = GBT_get_species_data(gb_main);
100    gb_table_data   = GB_search(gb_main, "table_data", GB_CREATE_CONTAINER);
101}
102
103AP_tree_root::~AP_tree_root() {
104    delete get_root_node();
105    free(gone_tree_name);
106    ap_assert(!get_root_node());
107}
108
109bool AP_tree_root::is_tree_updated() {
110    GBDATA *gbtree = get_gb_tree();
111    if (gbtree) {
112        GB_transaction ta(gbtree);
113        return GB_read_clock(gbtree)>tree_timer;
114    }
115    return true;
116}
117
118bool AP_tree_root::is_species_updated() {
119    if (gb_species_data) {
120        GB_transaction ta(gb_species_data);
121        return
122            GB_read_clock(gb_species_data)>species_timer ||
123            GB_read_clock(gb_table_data)>table_timer;
124    }
125    return true;
126}
127
128void AP_tree_root::update_timers() {
129    if (gb_species_data) {
130        GB_transaction  ta(GB_get_root(gb_species_data));
131        GBDATA         *gbtree = get_gb_tree();
132        if (gbtree) tree_timer = GB_read_clock(gbtree);
133        species_timer          = GB_read_clock(gb_species_data);
134        table_timer            = GB_read_clock(gb_table_data);
135    }
136}
137
138/*!***************************************************************************************
139************           AP_tree                     **********
140*****************************************************************************************/
141
142static void ap_tree_node_deleted(GBDATA *, AP_tree *tree) {
143    tree->gb_node = 0;
144}
145
146AP_tree::~AP_tree() {
147    if (gr.callback_exists && gb_node) {
148        GB_remove_callback(gb_node, GB_CB_DELETE, makeDatabaseCallback(ap_tree_node_deleted, this));
149    }
150
151    AP_tree_root *root = get_tree_root();
152    if (root) root->inform_about_delete(this);
153}
154
155void AP_tree::clear_branch_flags() {
156    br.clear();
157    if (!is_leaf) {
158        get_leftson()->clear_branch_flags();
159        get_rightson()->clear_branch_flags();
160    }
161}
162
163void AP_tree::initial_insert(AP_tree *new_brother, AP_tree_root *troot) {
164    ap_assert(troot);
165    ap_assert(is_leaf);
166    ap_assert(new_brother->is_leaf);
167    ap_assert(!troot->get_root_node());
168
169    ASSERT_VALID_TREE(this);
170    ASSERT_VALID_TREE(new_brother);
171
172    AP_tree *new_root = DOWNCAST(AP_tree*, troot->makeNode());
173
174    new_root->leftson  = this;
175    new_root->rightson = new_brother;
176    new_root->father   = NULL;
177
178    father              = new_root;
179    new_brother->father = new_root;
180
181    new_root->leftlen  = 0.5;
182    new_root->rightlen = 0.5;
183
184    troot->change_root(NULL, new_root);
185
186    set_tree_root(troot);
187    new_brother->set_tree_root(troot);
188}
189
190void AP_tree::insert(AP_tree *new_brother) {
191    ASSERT_VALID_TREE(this);
192    ASSERT_VALID_TREE(new_brother);
193
194    AP_tree  *new_tree = DOWNCAST(AP_tree*, new_brother->get_tree_root()->makeNode());
195    AP_FLOAT  laenge;
196
197    new_tree->leftson  = this;
198    new_tree->rightson = new_brother;
199    new_tree->father   = new_brother->father;
200    father             = new_tree;
201
202    if (new_brother->father) {
203        if (new_brother->father->leftson == new_brother) {
204            laenge = new_brother->father->leftlen = new_brother->father->leftlen*.5;
205            new_brother->father->leftson = new_tree;
206        }
207        else {
208            laenge = new_brother->father->rightlen = new_brother->father->rightlen*.5;
209            new_brother->father->rightson = new_tree;
210        }
211    }
212    else {
213        laenge = 0.5;
214    }
215    new_tree->leftlen   = laenge;
216    new_tree->rightlen  = laenge;
217    new_brother->father = new_tree;
218
219    AP_tree_root *troot = new_brother->get_tree_root();
220    ap_assert(troot); // Note: initial_insert() has to be used to build initial tree
221
222    if (!new_tree->father) troot->change_root(new_brother, new_tree);
223    else new_tree->set_tree_root(troot);
224    set_tree_root(troot);
225
226    ASSERT_VALID_TREE(troot->get_root_node());
227}
228
229void AP_tree_root::change_root(RootedTree *oldroot, RootedTree *newroot) {
230    if (root_changed_cb) {
231        root_changed_cb(root_changed_cd, DOWNCAST(AP_tree*, oldroot), DOWNCAST(AP_tree*, newroot));
232    }
233    if (!oldroot) {
234        ap_assert(newroot);
235        if (gb_tree_gone) {                         // when tree was temporarily deleted (e.g. by 'Remove & add all')
236            set_gb_tree(gb_tree_gone);              // re-use previous DB entry
237            gb_tree_gone = NULL;
238        }
239    }
240    if (!newroot) {                                 // tree empty
241        GBDATA *gbtree = get_gb_tree();
242        if (gbtree) {
243            ap_assert(gb_tree_gone == NULL);        // no tree should be remembered yet
244            gb_tree_gone = gbtree;                  // remember for deletion (done in AP_tree::save)
245        }
246    }
247    ARB_seqtree_root::change_root(oldroot, newroot);
248}
249
250void AP_tree_root::inform_about_delete(AP_tree *del) {
251    if (node_deleted_cb) node_deleted_cb(node_deleted_cd, del);
252}
253
254void AP_tree_root::set_root_changed_callback(AP_rootChangedCb cb, void *cd) {
255    root_changed_cb = cb;
256    root_changed_cd = cd;
257}
258
259void AP_tree_root::set_node_deleted_callback(AP_nodeDelCb cb, void *cd) {
260    node_deleted_cb = cb;
261    node_deleted_cd = cd;
262}
263
264
265void AP_tree::remove() {
266    // remove this + father from tree
267    // Note: does not delete this or father!
268
269    ASSERT_VALID_TREE(this);
270    if (father == 0) {
271        get_tree_root()->change_root(this, NULL); // tell AP_tree_root that the root node has been removed
272        forget_origin(); // removed nodes are rootless
273    }
274    else {
275        AP_tree      *brother     = get_brother();  // brother remains in tree
276        GBT_LEN       brothersLen = brother->get_branchlength();
277        AP_tree      *fath        = get_father();   // fath of this is removed as well
278        ARB_seqtree  *grandfather = fath->get_father();
279        AP_tree_root *troot       = get_tree_root();
280
281        if (fath->gb_node) {                      // move inner information to remaining subtree
282            if (!brother->gb_node && !brother->is_leaf) {
283                brother->gb_node = fath->gb_node;
284                fath->gb_node    = 0;
285            }
286        }
287
288        if (grandfather) {
289            brother->unlink_from_father();
290
291            bool wasLeftSon = fath->is_leftson();
292            fath->unlink_from_father();
293
294            if (wasLeftSon) {
295                ap_assert(!grandfather->leftson);
296                grandfather->leftlen += brothersLen;
297                grandfather->leftson  = brother;
298            }
299            else {
300                ap_assert(!grandfather->rightson);
301                grandfather->rightlen += brothersLen;
302                grandfather->rightson  = brother;
303            }
304            brother->father = grandfather;
305        }
306        else {                                      // father is root, make brother the new root
307            if (brother->is_leaf) {
308                troot->change_root(fath, NULL);     // erase tree from root
309            }
310            else {
311                brother->unlink_from_father();
312                troot->change_root(fath, brother);
313            }
314        }
315
316        ap_assert(fath == father);
317
318        ASSERT_VALID_TREE_OR_NULL(troot->get_root_node());
319
320        troot->inform_about_delete(fath);
321        troot->inform_about_delete(this);
322
323        fath->forget_origin();
324        ASSERT_VALID_TREE(fath);
325    }
326}
327
328GB_ERROR AP_tree::cantMoveNextTo(AP_tree *new_brother) {
329    GB_ERROR error = 0;
330
331    if (!father)                                error = "Can't move the root of the tree";
332    else if (!new_brother->father)              error = "Can't move to the root of the tree";
333    else if (new_brother->father == father)     error = "Already there";
334    else if (!father->father)                   error = "Can't move son of root";
335    else if (new_brother->is_inside(this))      error = "Can't move a subtree into itself";
336
337    return error;
338}
339
340void AP_tree::moveNextTo(AP_tree *new_brother, AP_FLOAT rel_pos) {
341    // rel_pos == 0.0 -> at father
342    //         == 1.0 -> at brother
343
344    ap_assert(father);
345    ap_assert(new_brother->father);
346    ap_assert(new_brother->father != father);       // already there
347    ap_assert(!new_brother->is_inside(this));       // can't move tree into itself
348
349    if (father->leftson != this) get_father()->swap_sons();
350
351    if (father->father == 0) {
352        get_brother()->father = 0;
353        get_tree_root()->change_root(get_father(), get_brother());
354    }
355    else {
356        ARB_seqtree *grandfather = get_father()->get_father();
357        if (father == new_brother) {    // just pull branches !!
358            new_brother  = get_brother();
359            if (grandfather->leftson == father) {
360                rel_pos *= grandfather->leftlen / (father->rightlen+grandfather->leftlen);
361            }
362            else {
363                rel_pos *= grandfather->rightlen / (father->rightlen+grandfather->rightlen);
364            }
365        }
366        else if (new_brother->father == father) { // just pull branches !!
367            rel_pos =
368                1.0 + (rel_pos-1.0) * father->rightlen
369                /
370                (father->rightlen + (grandfather->leftson == father ? grandfather->leftlen : grandfather->rightlen));
371        }
372
373        if (grandfather->leftson == father) {
374            grandfather->leftlen     += father->rightlen;
375            grandfather->leftson      = father->rightson;
376            father->rightson->father  = grandfather;
377        }
378        else {
379            grandfather->rightlen    += father->rightlen;
380            grandfather->rightson     = father->rightson;
381            father->rightson->father  = grandfather;
382        }
383    }
384
385    ARB_seqtree *new_tree          = get_father();
386    ARB_seqtree *brother_father    = new_brother->get_father();
387    AP_FLOAT  laenge;
388
389    if (brother_father->leftson == new_brother) {
390        laenge  = brother_father->leftlen;
391        laenge -= brother_father->leftlen = laenge * rel_pos;
392        new_brother->father->leftson = new_tree;
393    }
394    else {
395        laenge  = brother_father->rightlen;
396        laenge -= brother_father->rightlen = laenge * rel_pos;
397        brother_father->rightson = new_tree;
398    }
399
400    new_tree->rightlen  = laenge;
401    new_brother->father = new_tree;
402    new_tree->rightson  = new_brother;
403    new_tree->father    = brother_father;
404}
405
406void AP_tree::swap_assymetric(AP_TREE_SIDE mode) {
407    // mode AP_LEFT exchanges lefts with brother
408    // mode AP_RIGHT exchanges rights with brother
409
410    ap_assert(!is_leaf);                           // cannot swap leafs
411    ap_assert(father);                             // cannot swap root (has no brother)
412    ap_assert(mode == AP_LEFT || mode == AP_RIGHT); // illegal mode
413
414    ARB_seqtree *pntr;
415
416    if (father->father == 0) { // father is root
417        AP_tree *pntr_brother = get_brother();
418        if (!pntr_brother->is_leaf) {
419            if (mode == AP_LEFT) {
420                pntr_brother->leftson->father = this;
421                pntr                          = pntr_brother->get_leftson();
422                pntr_brother->leftson         = leftson;
423                leftson->father               = pntr_brother;
424                leftson                       = pntr;
425            }
426            else {
427                pntr_brother->leftson->father = this;
428                rightson->father              = pntr_brother;
429                pntr                          = pntr_brother->get_leftson();
430                pntr_brother->leftson         = rightson;
431                rightson                      = pntr;
432            }
433        }
434    }
435    else {
436        if (mode == AP_LEFT) { // swap leftson with brother
437            if (father->leftson == this) {
438                father->rightson->father = this;
439                leftson->father          = father;
440                pntr                     = get_father()->get_rightson();
441                AP_FLOAT help_len        = father->rightlen;
442                father->rightlen         = leftlen;
443                leftlen                  = help_len;
444                father->rightson         = leftson;
445                leftson                  = pntr;
446            }
447            else {
448                father->leftson->father = this;
449                leftson->father         = father;
450                pntr                    = get_father()->get_leftson();
451                AP_FLOAT help_len       = father->leftlen;
452                father->leftlen         = leftlen;
453                leftlen                 = help_len;
454                father->leftson         = leftson;
455                leftson                 = pntr;
456            }
457        }
458        else { // swap rightson with brother
459            if (father->leftson == this) {
460                father->rightson->father = this;
461                rightson->father         = father;
462                pntr                     = get_father()->get_rightson();
463                AP_FLOAT help_len        = father->rightlen;
464                father->rightlen         = rightlen;
465                rightlen                 = help_len;
466                father->rightson         = rightson;
467                rightson                 = pntr;
468            }
469            else {
470                father->leftson->father = this;
471                rightson->father        = father;
472                pntr                    = get_father()->get_leftson();
473                AP_FLOAT help_len       = father->leftlen;
474                father->leftson         = rightson;
475                father->leftlen         = rightlen;
476                rightlen                = help_len;
477                rightson                = pntr;
478            }
479        }
480    }
481}
482
483void AP_tree::set_root() {
484    if (at_root()) return; // already root
485
486    {
487        AP_tree           *old_brother = 0;
488        AP_branch_members  br1         = br;
489        AP_tree           *pntr;
490
491        for  (pntr = get_father(); pntr->father; pntr = pntr->get_father()) {
492            AP_branch_members br2 = pntr->br;
493            pntr->br              = br1;
494            br1                   = br2;
495            old_brother           = pntr;
496        }
497        if (pntr->leftson == old_brother) {
498            pntr->get_rightson()->br = br1;
499        }
500    }
501
502    ARB_seqtree::set_root();
503}
504
505
506inline int tree_read_byte(GBDATA *tree, const char *key, int init) {
507    if (tree) {
508        GBDATA *gbd = GB_entry(tree, key);
509        if (gbd) return GB_read_byte(gbd);
510    }
511    return init;
512}
513
514inline float tree_read_float(GBDATA *tree, const char *key, float init) {
515    if (tree) {
516        GBDATA *gbd = GB_entry(tree, key);
517        if (gbd) return GB_read_float(gbd);
518    }
519    return init;
520}
521
522
523
524//! moves all node/leaf information from struct GBT_TREE to AP_tree
525void AP_tree::load_node_info() {
526    gr.spread          = tree_read_float(gb_node, "spread",          1.0);
527    gr.left_angle      = tree_read_float(gb_node, "left_angle",      0.0);
528    gr.right_angle     = tree_read_float(gb_node, "right_angle",     0.0);
529    gr.left_linewidth  = tree_read_byte (gb_node, "left_linewidth",  0);
530    gr.right_linewidth = tree_read_byte (gb_node, "right_linewidth", 0);
531    gr.grouped         = tree_read_byte (gb_node, "grouped",         0);
532}
533
534void AP_tree::load_subtree_info() {
535    load_node_info();
536    if (!is_leaf) {
537        get_leftson()->load_subtree_info();
538        get_rightson()->load_subtree_info();
539    }
540}
541
542#if defined(DEBUG)
543#if defined(DEVEL_RALF)
544#define DEBUG_tree_write_byte
545#endif // DEVEL_RALF
546#endif // DEBUG
547
548
549static GB_ERROR tree_write_byte(GBDATA *gb_tree, AP_tree *node, short i, const char *key, int init) {
550    GBDATA *gbd;
551    GB_ERROR error = 0;
552    if (i==init) {
553        if (node->gb_node) {
554            gbd = GB_entry(node->gb_node, key);
555            if (gbd) {
556#if defined(DEBUG_tree_write_byte)
557                printf("[tree_write_byte] deleting db entry %p\n", gbd);
558#endif // DEBUG_tree_write_byte
559                GB_delete(gbd);
560            }
561        }
562    }
563    else {
564        if (!node->gb_node) {
565            node->gb_node = GB_create_container(gb_tree, "node");
566#if defined(DEBUG_tree_write_byte)
567            printf("[tree_write_byte] created node-container %p\n", node->gb_node);
568#endif // DEBUG_tree_write_byte
569        }
570        gbd = GB_entry(node->gb_node, key);
571        if (!gbd) {
572            gbd = GB_create(node->gb_node, key, GB_BYTE);
573#if defined(DEBUG_tree_write_byte)
574            printf("[tree_write_byte] created db entry %p\n", gbd);
575#endif // DEBUG_tree_write_byte
576        }
577        error = GB_write_byte(gbd, i);
578    }
579    return error;
580}
581
582static GB_ERROR tree_write_float(GBDATA *gb_tree, AP_tree *node, float f, const char *key, float init) {
583    GB_ERROR error = NULL;
584    if (f==init) {
585        if (node->gb_node) {
586            GBDATA *gbd    = GB_entry(node->gb_node, key);
587            if (gbd) error = GB_delete(gbd);
588        }
589    }
590    else {
591        if (!node->gb_node) {
592            node->gb_node             = GB_create_container(gb_tree, "node");
593            if (!node->gb_node) error = GB_await_error();
594        }
595        if (!error) error = GBT_write_float(node->gb_node, key, f);
596    }
597    return error;
598}
599
600GB_ERROR AP_tree::tree_write_tree_rek(GBDATA *gb_tree) {
601    GB_ERROR error = NULL;
602    if (!is_leaf) {
603        error             = get_leftson()->tree_write_tree_rek(gb_tree);
604        if (!error) error = get_rightson()->tree_write_tree_rek(gb_tree);
605
606        if (!error) error = tree_write_float(gb_tree, this, gr.spread,          "spread",          1.0);
607        if (!error) error = tree_write_float(gb_tree, this, gr.left_angle,      "left_angle",      0.0);
608        if (!error) error = tree_write_float(gb_tree, this, gr.right_angle,     "right_angle",     0.0);
609        if (!error) error = tree_write_byte (gb_tree, this, gr.left_linewidth,  "left_linewidth",  0);
610        if (!error) error = tree_write_byte (gb_tree, this, gr.right_linewidth, "right_linewidth", 0);
611        if (!error) error = tree_write_byte (gb_tree, this, gr.grouped,         "grouped",         0);
612    }
613    return error;
614}
615
616GB_ERROR AP_tree_root::saveToDB() {
617    GB_ERROR  error  = GB_push_transaction(get_gb_main());
618    if (get_gb_tree()) {
619        error = get_root_node()->tree_write_tree_rek(get_gb_tree());
620    }
621    else {
622        ap_assert(!gb_tree_gone);      // should have been handled by caller (e.g. in AWT_graphic_tree::save)
623    }
624    if (!error) {
625        if (!get_gb_tree() && gone_tree_name) { // tree was deleted before
626            GBDATA *gb_tree_exists = GBT_find_tree(get_gb_main(), gone_tree_name);
627            if (gb_tree_exists) {
628                error = "tree already exists";
629            }
630            else {
631                error = GBT_write_tree(get_gb_main(), gone_tree_name, get_root_node());
632                if (!error) {
633                    gb_tree_exists = GBT_find_tree(get_gb_main(), gone_tree_name);
634                    ap_assert(gb_tree_exists);
635                    if (gb_tree_exists) {
636                        set_gb_tree_and_name(GBT_find_tree(get_gb_main(), gone_tree_name), gone_tree_name);
637                        aw_message(GBS_global_string("Recreated previously deleted '%s'", gone_tree_name));
638                        freenull(gone_tree_name);
639                    }
640                }
641            }
642
643            if (error) aw_message(GBS_global_string("Failed to recreate '%s' (Reason: %s)", gone_tree_name, error));
644        }
645
646        if (!error) error = ARB_seqtree_root::saveToDB();
647    }
648    if (!error) update_timers();
649
650    return GB_end_transaction(get_gb_main(), error);
651}
652
653
654GB_ERROR AP_tree::move_group_info(AP_tree *new_group) {
655    GB_ERROR error = 0;
656    if (is_leaf || !name) {
657        error = "Please select a valid group";
658    }
659    else if (!gb_node) {
660        error = "Internal Error: group with name is missing DB-entry";
661    }
662    else if (new_group->is_leaf) {
663        if (new_group->name) {
664            error = GBS_global_string("'%s' is not a valid target for group information of '%s'.", new_group->name, name);
665        }
666        else if (new_group->gb_node) {
667            error = "Internal Error: Target node already has a database entry (but no name)";
668        }
669    }
670
671    if (!error) {
672        if (new_group->name) {
673            if (!new_group->gb_node) {
674                error = "Internal Error: Target node has a database entry (but no name)";
675            }
676            else { // exchange information of two groups
677                GBDATA *tmp_node   = new_group->gb_node;
678                char   *tmp_name   = new_group->name;
679                new_group->gb_node = gb_node;
680                new_group->name    = name;
681                name               = tmp_name;
682                gb_node            = tmp_node;
683            }
684        }
685        else { // move group info
686            new_group->gb_node = this->gb_node;
687            new_group->name    = this->name;
688            this->name         = 0;
689            this->gb_node      = 0;
690        }
691
692        this->load_node_info();
693        new_group->load_node_info();
694
695        {
696            GBDATA *gb_group_name;
697            gb_group_name = GB_entry(new_group->gb_node, "group_name");
698            if (gb_group_name) GB_touch(gb_group_name); // force taxonomy reload
699        }
700    }
701    return error;
702}
703
704void AP_tree::update() {
705    GB_transaction ta(get_tree_root()->get_gb_main());
706    get_tree_root()->update_timers();
707}
708
709void AP_tree::update_subtree_information() {
710    gr.hidden = get_father() ? (get_father()->gr.hidden || get_father()->gr.grouped) : 0;
711
712    if (is_leaf) {
713        gr.view_sum = 1;
714        gr.leaf_sum = 1;
715
716        gr.max_tree_depth = 0.0;
717        gr.min_tree_depth = 0.0;
718
719        bool is_marked = gb_node && GB_read_flag(gb_node);
720
721        gr.has_marked_children = is_marked;
722
723        // colors:
724        if (gb_node) {
725            if (is_marked) {
726                gr.gc = AWT_GC_SELECTED;
727            }
728            else {
729                // check for user color
730                long color_group = AWT_species_get_dominant_color(gb_node);
731                if (color_group == 0) {
732                    gr.gc = AWT_GC_NSELECTED;
733                }
734                else {
735                    gr.gc = AWT_GC_FIRST_COLOR_GROUP+color_group-1;
736                }
737            }
738        }
739        else {
740            gr.gc = AWT_GC_ZOMBIES;
741        }
742    }
743    else {
744        get_leftson()->update_subtree_information();
745        get_rightson()->update_subtree_information();
746
747        {
748            AP_tree_members& left  = get_leftson()->gr;
749            AP_tree_members& right = get_rightson()->gr;
750
751            gr.leaf_sum = left.leaf_sum + right.leaf_sum;
752            gr.view_sum = left.view_sum + right.view_sum;
753            if (gr.grouped) {
754                gr.view_sum = (int)pow((double)(gr.leaf_sum - GROUPED_SUM + 9), .33);
755            }
756
757            gr.min_tree_depth = std::min(leftlen+left.min_tree_depth, rightlen+right.min_tree_depth);
758            gr.max_tree_depth = std::max(leftlen+left.max_tree_depth, rightlen+right.max_tree_depth);
759
760            gr.has_marked_children = left.has_marked_children || right.has_marked_children;
761
762            // colors:
763            if (left.gc == right.gc) gr.gc = left.gc;
764
765            else if (left.gc == AWT_GC_SELECTED || right.gc == AWT_GC_SELECTED) gr.gc = AWT_GC_UNDIFF;
766
767            else if (left.gc  == AWT_GC_ZOMBIES) gr.gc = right.gc;
768            else if (right.gc == AWT_GC_ZOMBIES) gr.gc = left.gc;
769
770            else if (left.gc == AWT_GC_UNDIFF || right.gc == AWT_GC_UNDIFF) gr.gc = AWT_GC_UNDIFF;
771
772            else {
773                ap_assert(left.gc != AWT_GC_SELECTED && right.gc != AWT_GC_SELECTED);
774                ap_assert(left.gc != AWT_GC_UNDIFF   && right.gc != AWT_GC_UNDIFF);
775                gr.gc = AWT_GC_NSELECTED;
776            }
777        }
778    }
779}
780
781unsigned AP_tree::count_leafs() const {
782    return is_leaf
783        ? 1
784        : get_leftson()->count_leafs() + get_rightson()->count_leafs();
785}
786
787int AP_tree::colorize(GB_HASH *hashptr) {
788    // colorizes the tree according to 'hashptr'
789    // hashkey   = species id
790    // hashvalue = gc
791
792    int res;
793    if (is_leaf) {
794        if (gb_node) {
795            res = GBS_read_hash(hashptr, name);
796            if (!res && GB_read_flag(gb_node)) { // marked but not in hash -> black
797                res = AWT_GC_BLACK;
798            }
799        }
800        else {
801            res = AWT_GC_ZOMBIES;
802        }
803    }
804    else {
805        int l = get_leftson()->colorize(hashptr);
806        int r = get_rightson()->colorize(hashptr);
807
808        if      (l == r)              res = l;
809        else if (l == AWT_GC_ZOMBIES) res = r;
810        else if (r == AWT_GC_ZOMBIES) res = l;
811        else                          res = AWT_GC_UNDIFF;
812    }
813    gr.gc = res;
814    return res;
815}
816
817void AP_tree::compute_tree() {
818    GB_transaction ta(get_tree_root()->get_gb_main());
819    update_subtree_information();
820}
821
822GB_ERROR AP_tree_root::loadFromDB(const char *name) {
823    GB_ERROR error = ARB_seqtree_root::loadFromDB(name);
824    if (!error) {
825        AP_tree *rNode = DOWNCAST(AP_tree*, get_root_node());
826        rNode->load_subtree_info();
827    }
828    update_timers(); // maybe after link() ? // @@@ really do if error?
829    return error;
830}
831
832GB_ERROR AP_tree::relink() {
833    GB_transaction ta(get_tree_root()->get_gb_main()); // open close a transaction
834    GB_ERROR error = GBT_link_tree(this, get_tree_root()->get_gb_main(), false, 0, 0); // no status
835    get_tree_root()->update_timers();
836    return error;
837}
838
839AP_UPDATE_FLAGS AP_tree::check_update() {
840    AP_tree_root *troot   = get_tree_root();
841    GBDATA       *gb_main = troot->get_gb_main();
842
843    if (!gb_main) {
844        return AP_UPDATE_RELOADED;
845    }
846    else {
847        GB_transaction ta(gb_main);
848
849        if (troot->is_tree_updated()) return AP_UPDATE_RELOADED;
850        if (troot->is_species_updated()) return AP_UPDATE_RELINKED;
851        return AP_UPDATE_OK;
852    }
853}
854
855#if defined(WARN_TODO)
856#warning buildLeafList, buildNodeList and buildBranchList should return a AP_tree_list (new class!)
857#endif
858
859void AP_tree::buildLeafList_rek(AP_tree **list, long& num) {
860    // builds a list of all species
861    if (!is_leaf) {
862        get_leftson()->buildLeafList_rek(list, num);
863        get_rightson()->buildLeafList_rek(list, num);
864    }
865    else {
866        list[num] = this;
867        num++;
868    }
869}
870
871void AP_tree::buildLeafList(AP_tree **&list, long &num) {
872    num        = count_leafs();
873    list       = new AP_tree *[num+1];
874    list[num]  = 0;
875    long count = 0;
876
877    buildLeafList_rek(list, count);
878
879    ap_assert(count == num);
880}
881
882void AP_tree::buildNodeList_rek(AP_tree **list, long& num) {
883    // builds a list of all inner nodes (w/o root node)
884    if (!is_leaf) {
885        if (father) list[num++] = this;
886        get_leftson()->buildNodeList_rek(list, num);
887        get_rightson()->buildNodeList_rek(list, num);
888    }
889}
890
891void AP_tree::buildNodeList(AP_tree **&list, long &num) {
892    num = this->count_leafs()-1;
893    list = new AP_tree *[num+1];
894    list[num] = 0;
895    num  = 0;
896    buildNodeList_rek(list, num);
897}
898
899void AP_tree::buildBranchList_rek(AP_tree **list, long& num, bool create_terminal_branches, int deep) {
900    // builds a list of all species
901    // (returns pairs of leafs/father and nodes/father)
902
903    if (deep) {
904        if (father && (create_terminal_branches || !is_leaf)) {
905            if (father->father) {
906                list[num++] = this;
907                list[num++] = get_father();
908            }
909            else {                  // root
910                if (father->leftson == this) {
911                    list[num++] = this;
912                    list[num++] = get_brother();
913                }
914            }
915        }
916        if (!is_leaf) {
917            get_leftson() ->buildBranchList_rek(list, num, create_terminal_branches, deep-1);
918            get_rightson()->buildBranchList_rek(list, num, create_terminal_branches, deep-1);
919        }
920    }
921}
922
923void AP_tree::buildBranchList(AP_tree **&list, long &num, bool create_terminal_branches, int deep) {
924    if (deep>=0) {
925        num = 2;
926        for (int i=0; i<deep; i++) num *= 2;
927    }
928    else {
929        num = count_leafs() * (create_terminal_branches ? 2 : 1);
930    }
931
932    ap_assert(num >= 0);
933
934    list = new AP_tree *[num*2+4];
935
936    if (num) {
937        long count = 0;
938
939        buildBranchList_rek(list, count, create_terminal_branches, deep);
940        list[count] = 0;
941        num         = count/2;
942    }
943}
944
945
946long AP_tree_root::remove_leafs(AWT_RemoveType awt_remove_type) {
947    // may remove the complete tree (if awt_remove_type does not contain AWT_REMOVE_BUT_DONT_FREE)
948
949    ASSERT_VALID_TREE(get_root_node());
950
951    AP_tree **list;
952    long      count;
953    get_root_node()->buildLeafList(list, count);
954
955    GB_transaction ta(get_gb_main());
956    long removed = 0;
957
958    for (long i=0; i<count; i++) {
959        bool     removeNode = false;
960        AP_tree *leaf       = list[i];
961
962        if (leaf->gb_node) {
963            if ((awt_remove_type & AWT_REMOVE_NO_SEQUENCE) && !leaf->get_seq()) {
964                removeNode = true;
965            }
966            else if (awt_remove_type & (AWT_REMOVE_MARKED|AWT_REMOVE_UNMARKED)) {
967                long flag  = GB_read_flag(list[i]->gb_node);
968                removeNode = (flag && (awt_remove_type&AWT_REMOVE_MARKED)) || (!flag && (awt_remove_type&AWT_REMOVE_UNMARKED));
969            }
970        }
971        else {
972            if (awt_remove_type & AWT_REMOVE_ZOMBIES) {
973                removeNode = true;
974            }
975        }
976
977        if (removeNode) {
978            list[i]->remove();
979            removed++;
980            if (!(awt_remove_type & AWT_REMOVE_BUT_DONT_FREE)) {
981                delete list[i]->father;
982            }
983            if (!get_root_node()) {
984                break; // tree has been deleted
985            }
986        }
987        ASSERT_VALID_TREE(get_root_node());
988    }
989    delete [] list;
990
991    ASSERT_VALID_TREE_OR_NULL(get_root_node());
992    return removed;
993}
994
995// ----------------------------------------
996
997AP_tree ** AP_tree::getRandomNodes(int anzahl) {
998    // function returns a random constructed tree
999    // root is tree with species (needed to build a list of species)
1000
1001    AP_tree **retlist = NULL;
1002    if (anzahl) {
1003        AP_tree **list; 
1004        long      sumnodes;
1005        buildNodeList(list, sumnodes);
1006
1007        if (sumnodes) {
1008            retlist = (AP_tree **)calloc(anzahl, sizeof(AP_tree *));
1009
1010            long count = sumnodes;
1011            for (int i=0; i< anzahl; i++) {
1012                long num = GB_random(count);
1013
1014                retlist[i] = list[num]; // export node
1015                count--;                // exclude node
1016
1017                list[num]   = list[count];
1018                list[count] = retlist[i];
1019
1020                if (count == 0) count = sumnodes; // restart it
1021            }
1022        }
1023        delete [] list;
1024    }
1025    return retlist;
1026}
1027
1028// --------------------------------------------------------------------------------
1029
1030template <typename T>
1031class ValueCounter {
1032    T   min, max, sum;
1033    int count;
1034
1035    char *mean_min_max_impl() const;
1036    char *mean_min_max_percent_impl() const;
1037
1038    mutable char *buf;
1039    const char *set_buf(char *content) const { freeset(buf, content); return buf; }
1040
1041public:
1042    ValueCounter()
1043        : min(INT_MAX),
1044          max(INT_MIN),
1045          sum(0),
1046          count(0),
1047          buf(NULL)
1048    {}
1049    ValueCounter(const ValueCounter<T>& other)
1050        : min(other.min),
1051          max(other.max),
1052          sum(other.sum),
1053          count(other.count),
1054          buf(NULL)
1055    {}
1056    ~ValueCounter() { free(buf); }
1057
1058    DECLARE_ASSIGNMENT_OPERATOR(ValueCounter<T>);
1059
1060    void count_value(T val) {
1061        count++;
1062        min  = std::min(min, val);
1063        max  = std::max(max, val);
1064        sum += val;
1065    }
1066
1067    int get_count() const { return count; }
1068    T get_min() const { return min; }
1069    T get_max() const { return max; }
1070    double get_mean() const { return sum/double(count); }
1071
1072    const char *mean_min_max()         const { return count ? set_buf(mean_min_max_impl())         : "<not available>"; }
1073    const char *mean_min_max_percent() const { return count ? set_buf(mean_min_max_percent_impl()) : "<not available>"; }
1074
1075    ValueCounter<T>& operator += (const T& inc) {
1076        min += inc;
1077        max += inc;
1078        sum += inc*count;
1079        return *this;
1080    }
1081    ValueCounter<T>& operator += (const ValueCounter<T>& other) {
1082        min    = std::min(min, other.min);
1083        max    = std::max(max, other.max);
1084        sum   += other.sum;
1085        count += other.count;
1086        return *this;
1087    }
1088};
1089
1090template<typename T>
1091inline ValueCounter<T> operator+(const ValueCounter<T>& c1, const ValueCounter<T>& c2) {
1092    return ValueCounter<T>(c1) += c2;
1093}
1094template<typename T>
1095inline ValueCounter<T> operator+(const ValueCounter<T>& c, const T& inc) {
1096    return ValueCounter<T>(c) += inc;
1097}
1098
1099template<> char *ValueCounter<int>::mean_min_max_impl() const {
1100    return GBS_global_string_copy("%.2f (range: %i .. %i)", get_mean(), get_min(), get_max());
1101}
1102template<> char *ValueCounter<double>::mean_min_max_impl() const {
1103    return GBS_global_string_copy("%.2f (range: %.2f .. %.2f)", get_mean(), get_min(), get_max());
1104}
1105template<> char *ValueCounter<double>::mean_min_max_percent_impl() const {
1106    return GBS_global_string_copy("%.2f%% (range: %.2f%% .. %.2f%%)", get_mean()*100.0, get_min()*100.0, get_max()*100.0);
1107}
1108
1109class LongBranchMarker {
1110    double min_rel_diff;
1111    double min_abs_diff;
1112
1113    int leafs;
1114    int nonzeroleafs;
1115    int multifurcs;
1116
1117    ValueCounter<double> absdiff;
1118    ValueCounter<double> reldiff;
1119    ValueCounter<double> absdiff_marked;
1120    ValueCounter<double> reldiff_marked;
1121
1122    double perform_marking(AP_tree *at, bool& marked) {
1123        marked = false;
1124        if (at->is_leaf) {
1125            if (at->get_branchlength() != 0.0) {
1126                nonzeroleafs++;
1127            }
1128            leafs++;
1129            return 0.0;
1130        }
1131
1132        if (!at->is_root_node()) {
1133            if (at->get_branchlength() == 0.0) { // is multifurcation
1134                if (!at->get_father()->is_root_node() || at->is_leftson()) { // do not count two multifurcs @ sons of root
1135                    multifurcs++;
1136                }
1137            }
1138        }
1139
1140        bool   marked_left;
1141        bool   marked_right;
1142        double max = perform_marking(at->get_leftson(),  marked_left)  + at->leftlen;
1143        double min = perform_marking(at->get_rightson(), marked_right) + at->rightlen;
1144
1145        bool max_is_left = true;
1146        if (max<min) {
1147            double h = max; max = min; min = h;
1148            max_is_left = false;
1149        }
1150
1151        double abs_diff = max-min;
1152        absdiff.count_value(abs_diff);
1153
1154        double rel_diff = (max == 0.0) ? 0.0 : abs_diff/max;
1155        reldiff.count_value(rel_diff);
1156
1157        if (abs_diff>min_abs_diff && rel_diff>min_rel_diff) {
1158            if (max_is_left) {
1159                if (!marked_left) {
1160                    at->get_leftson()->mark_subtree();
1161                    marked = true;
1162                }
1163            }
1164            else {
1165                if (!marked_right) {
1166                    at->get_rightson()->mark_subtree();
1167                    marked = true;
1168                }
1169            }
1170        }
1171
1172        if (marked) { // just marked one of my subtrees
1173            absdiff_marked.count_value(abs_diff);
1174            reldiff_marked.count_value(rel_diff);
1175        }
1176        else {
1177            marked = marked_left||marked_right;
1178        }
1179
1180        return min; // use minimal distance for whole subtree
1181    }
1182
1183    static char *meanDiffs(const ValueCounter<double>& abs, const ValueCounter<double>& rel) {
1184        return GBS_global_string_copy(
1185            "Mean absolute diff: %s\n"
1186            "Mean relative diff: %s",
1187            abs.mean_min_max(), 
1188            rel.mean_min_max_percent());
1189    }
1190
1191public:
1192    LongBranchMarker(AP_tree *root, double min_rel_diff_, double min_abs_diff_)
1193        : min_rel_diff(min_rel_diff_),
1194          min_abs_diff(min_abs_diff_),
1195          leafs(0),
1196          nonzeroleafs(0),
1197          multifurcs(0)
1198    {
1199        bool UNUSED;
1200        perform_marking(root, UNUSED);
1201    }
1202
1203    const char *get_report() const {
1204        char *diffs_all    = meanDiffs(absdiff, reldiff);
1205        char *diffs_marked = meanDiffs(absdiff_marked, reldiff_marked);
1206
1207        int nodes     = leafs_2_nodes(leafs, UNROOTED);
1208        int edges     = nodes_2_edges(nodes);
1209        int zeroleafs = leafs-nonzeroleafs;
1210        int zeroedges = multifurcs+zeroleafs;
1211        int realedges = edges-zeroedges;
1212        int furcs     = nodes-leafs;    // = inner nodes
1213        int realfurcs = furcs-multifurcs;
1214
1215        int node_digits = log10(nodes)+1;
1216
1217        ap_assert(zeroleafs<=leafs);
1218        ap_assert(zeroedges<=edges);
1219        ap_assert(realedges<=edges);
1220        ap_assert(multifurcs<=furcs);
1221        ap_assert(realfurcs<=furcs);
1222
1223        const char *msg = GBS_global_string(
1224            "Unrooted tree contains %*i furcations,\n"
1225            "              of which %*i are multifurcations,\n"
1226            "                  i.e. %*i are \"real\" furcations.\n"
1227            "\n"
1228            "Unrooted tree contains %*i edges,\n"
1229            "              of which %*i have a length > zero.\n"
1230            "\n"
1231            "%s\n"
1232            "\n"
1233            "%i subtrees have been marked:\n"
1234            "%s\n"
1235            "\n",
1236            node_digits, furcs,
1237            node_digits, multifurcs,
1238            node_digits, realfurcs,
1239            node_digits, edges,
1240            node_digits, realedges,
1241            diffs_all,
1242            absdiff_marked.get_count(),
1243            diffs_marked);
1244
1245        free(diffs_all);
1246        free(diffs_marked);
1247
1248        return msg;
1249    }
1250};
1251
1252struct DepthMarker {
1253    // limits (marked if depth and dist are above)
1254    int    min_depth;
1255    double min_rootdist;
1256
1257    // current values (for recursion)
1258    int    depth;
1259    double dist;
1260
1261    // results
1262    ValueCounter<int>    depths,    depths_marked;
1263    ValueCounter<double> distances, distances_marked;
1264
1265    void perform_marking(AP_tree *at, AP_FLOAT atLen) {
1266        int depthInc = atLen == 0.0 ? 0 : 1;  // do NOT increase depth at multifurcations
1267
1268        depth += depthInc;
1269        dist  += atLen;
1270
1271        if (at->is_leaf) {
1272            depths.count_value(depth);
1273            distances.count_value(dist);
1274
1275            int mark = depth >= min_depth && dist >= min_rootdist;
1276            if (at->gb_node) {
1277                GB_write_flag(at->gb_node, mark);
1278                if (mark) {
1279                    depths_marked.count_value(depth);
1280                    distances_marked.count_value(dist);
1281                }
1282            }
1283        }
1284        else {
1285            perform_marking(at->get_leftson(), at->leftlen);
1286            perform_marking(at->get_rightson(), at->rightlen);
1287        }
1288
1289        depth -= depthInc;
1290        dist  -= atLen;
1291    }
1292
1293public:
1294    DepthMarker(AP_tree *root, int min_depth_, double min_rootdist_)
1295        : min_depth(min_depth_),
1296          min_rootdist(min_rootdist_),
1297          depth(0),
1298          dist(0.0)
1299    {
1300        perform_marking(root, 0.0);
1301    }
1302
1303    const char *get_report() const {
1304        int    leafs          = depths.get_count();
1305        int    marked         = depths_marked.get_count();
1306        double balanced_depth = log10(leafs) / log10(2);
1307
1308        const char *msg = GBS_global_string(
1309            "The optimal mean depth of a tree with %i leafs\n"
1310            "      would be %.2f\n"
1311            "\n"
1312            "Your tree:\n"
1313            "mean depth:    %s\n"
1314            "mean distance: %s\n"
1315            "\n"
1316            "%i species (%.2f%%) have been marked:\n"
1317            "mean depth:    %s\n"
1318            "mean distance: %s\n"
1319            ,
1320            leafs,
1321            balanced_depth,
1322            depths.mean_min_max(),
1323            distances.mean_min_max(), 
1324            marked, marked/double(leafs)*100.0,
1325            depths_marked.mean_min_max(), 
1326            distances_marked.mean_min_max()
1327            );
1328        return msg;
1329    }
1330};
1331
1332const char *AP_tree::mark_long_branches(double min_rel_diff, double min_abs_diff) {
1333    // look for asymmetric parts of the tree and mark all species with long branches
1334    return LongBranchMarker(this, min_rel_diff, min_abs_diff).get_report();
1335}
1336const char *AP_tree::mark_deep_leafs(int min_depth, double min_rootdist) {
1337    // mark all leafs with min_depth and min_rootdist
1338    return DepthMarker(this, min_depth, min_rootdist).get_report();
1339}
1340
1341// --------------------------------------------------------------------------------
1342
1343typedef ValueCounter<double> Distance;
1344
1345class DistanceCounter {
1346    Distance min, max, mean;
1347public:
1348
1349    void count_distance(const Distance& d) {
1350        mean.count_value(d.get_mean());
1351        min.count_value(d.get_min());
1352        max.count_value(d.get_max());
1353    }
1354
1355    int get_count() const { return mean.get_count(); }
1356
1357    char *get_report() const {
1358        return GBS_global_string_copy(
1359            "Mean mean distance: %s\n"
1360            "Mean min. distance: %s\n"
1361            "Mean max. distance: %s",
1362            mean.mean_min_max(), 
1363            min.mean_min_max(), 
1364            max.mean_min_max()
1365            );
1366    }
1367};
1368
1369class EdgeDistances {
1370    typedef map<AP_tree*, Distance> DistanceMap;
1371
1372    DistanceMap downdist; // inclusive length of branch itself
1373    DistanceMap updist;   // inclusive length of branch itself
1374
1375    GBT_LEN distSum; // of all distances in tree
1376
1377    arb_progress progress;
1378
1379    const Distance& calc_downdist(AP_tree *at, AP_FLOAT len) {
1380        if (at->is_leaf) {
1381            Distance d;
1382            d.count_value(len);
1383            downdist[at] = d;
1384
1385            progress.inc();
1386        }
1387        else {
1388            downdist[at] =
1389                calc_downdist(at->get_leftson(), at->leftlen) +
1390                calc_downdist(at->get_rightson(), at->rightlen) +
1391                len;
1392        }
1393        return downdist[at];
1394    }
1395
1396    const Distance& calc_updist(AP_tree *at, AP_FLOAT len) {
1397        ap_assert(at->father); // impossible - root has no updist!
1398
1399        AP_tree *father  = at->get_father();
1400        AP_tree *brother = at->get_brother();
1401
1402        if (father->father) {
1403            ap_assert(updist.find(father) != updist.end());
1404            ap_assert(downdist.find(brother) != downdist.end());
1405
1406            updist[at] = updist[father] + downdist[brother] + len;
1407        }
1408        else {
1409            ap_assert(downdist.find(brother) != downdist.end());
1410
1411            updist[at] = downdist[brother]+len;
1412        }
1413
1414        if (!at->is_leaf) {
1415            calc_updist(at->get_leftson(), at->leftlen);
1416            calc_updist(at->get_rightson(), at->rightlen);
1417        }
1418        else {
1419            progress.inc();
1420        }
1421       
1422        return updist[at];
1423    }
1424
1425    DistanceCounter alldists, markeddists;
1426
1427    void calc_distance_stats(AP_tree *at) {
1428        if (at->is_leaf) {
1429            ap_assert(updist.find(at) != updist.end());
1430
1431            const Distance& upwards = updist[at];
1432
1433            alldists.count_distance(upwards);
1434            if (at->gb_node && GB_read_flag(at->gb_node)) {
1435                markeddists.count_distance(upwards);
1436            }
1437
1438            progress.inc();
1439        }
1440        else {
1441            calc_distance_stats(at->get_leftson());
1442            calc_distance_stats(at->get_rightson());
1443        }
1444    }
1445
1446public:
1447
1448    EdgeDistances(AP_tree *root)
1449        : distSum(root->sum_child_lengths()),
1450          progress("Analysing distances", root->count_leafs()*3)
1451    {
1452        calc_downdist(root->get_leftson(),  root->leftlen);
1453        calc_downdist(root->get_rightson(), root->rightlen);
1454
1455        calc_updist(root->get_leftson(),  root->leftlen);
1456        calc_updist(root->get_rightson(), root->rightlen);
1457
1458        calc_distance_stats(root);
1459    }
1460
1461    const char *get_report() const {
1462        char *alldists_report    = alldists.get_report();
1463        char *markeddists_report = markeddists.get_report();
1464
1465        const char *msg = GBS_global_string(
1466            "Overall in-tree-distance (ITD): %.3f\n"
1467            "    per-species-distance (PSD): %.6f\n"
1468            "\n"
1469            "Distance statistic for %i leafs:\n"
1470            "(each leaf to all other leafs)\n"
1471            "\n"
1472            "%s\n"
1473            "\n"
1474            "Distance statistic for %i marked leafs:\n"
1475            "\n"
1476            "%s\n",
1477            distSum,
1478            distSum / alldists.get_count(),
1479            alldists.get_count(), alldists_report,
1480            markeddists.get_count(), markeddists_report);
1481
1482        free(markeddists_report);
1483        free(alldists_report);
1484
1485        return msg;
1486    }
1487};
1488
1489const char *AP_tree::analyse_distances() { return EdgeDistances(this).get_report(); }
1490
1491// --------------------------------------------------------------------------------
1492
1493static int ap_mark_degenerated(AP_tree *at, double degeneration_factor, double& max_degeneration) {
1494    // returns number of species in subtree
1495
1496    if (at->is_leaf) return 1;
1497
1498    int lSons = ap_mark_degenerated(at->get_leftson(), degeneration_factor, max_degeneration);
1499    int rSons = ap_mark_degenerated(at->get_rightson(), degeneration_factor, max_degeneration);
1500
1501    double this_degeneration = 0;
1502
1503    if (lSons<rSons) {
1504        this_degeneration = rSons/double(lSons);
1505        if (this_degeneration >= degeneration_factor) {
1506            at->get_leftson()->mark_subtree();
1507        }
1508
1509    }
1510    else if (rSons<lSons) {
1511        this_degeneration = lSons/double(rSons);
1512        if (this_degeneration >= degeneration_factor) {
1513            at->get_rightson()->mark_subtree();
1514        }
1515    }
1516
1517    if (this_degeneration >= max_degeneration) {
1518        max_degeneration = this_degeneration;
1519    }
1520
1521    return lSons+rSons;
1522}
1523
1524const char *AP_tree::mark_degenerated_branches(double degeneration_factor) {
1525    // marks all species in degenerated branches.
1526    // For all nodes, where one branch contains 'degeneration_factor' more species than the
1527    // other branch, the smaller branch is considered degenerated.
1528
1529    double max_degeneration = 0;
1530    ap_mark_degenerated(this, degeneration_factor, max_degeneration);
1531    return GBS_global_string("Maximum degeneration = %.2f", max_degeneration);
1532}
1533
1534static int ap_mark_duplicates_rek(AP_tree *at, GB_HASH *seen_species) {
1535    if (at->is_leaf) {
1536        if (at->name) {
1537            if (GBS_read_hash(seen_species, at->name)) { // already seen -> mark species
1538                if (at->gb_node) {
1539                    GB_write_flag(at->gb_node, 1);
1540                }
1541                else { // duplicated zombie
1542                    return 1;
1543                }
1544            }
1545            else { // first occurrence
1546                GBS_write_hash(seen_species, at->name, 1);
1547            }
1548        }
1549    }
1550    else {
1551        return
1552            ap_mark_duplicates_rek(at->get_leftson(), seen_species) +
1553            ap_mark_duplicates_rek(at->get_rightson(), seen_species);
1554    }
1555    return 0;
1556}
1557
1558void AP_tree::mark_duplicates() {
1559    GB_HASH *seen_species = GBS_create_hash(gr.leaf_sum, GB_IGNORE_CASE);
1560
1561    int dup_zombies = ap_mark_duplicates_rek(this, seen_species);
1562    if (dup_zombies) {
1563        aw_message(GBS_global_string("Warning: Detected %i duplicated zombies (can't mark them)", dup_zombies));
1564    }
1565    GBS_free_hash(seen_species);
1566}
1567
1568static double ap_just_tree_rek(AP_tree *at) {
1569    if (at->is_leaf) {
1570        return 0.0;
1571    }
1572    else {
1573        double bl = ap_just_tree_rek(at->get_leftson());
1574        double br = ap_just_tree_rek(at->get_rightson());
1575
1576        double l = at->leftlen + at->rightlen;
1577        double diff = fabs(bl - br);
1578        if (l < diff * 1.1) l = diff * 1.1;
1579        double go = (bl + br + l) * .5;
1580        at->leftlen = go - bl;
1581        at->rightlen = go - br;
1582        return go;
1583    }
1584}
1585
1586
1587void AP_tree::justify_branch_lenghs(GBDATA *gb_main) {
1588    // shift branches to create a symmetric looking tree
1589    GB_transaction ta(gb_main);
1590    ap_just_tree_rek(this);
1591}
1592
1593static void relink_tree_rek(AP_tree *node, void (*relinker)(GBDATA *&ref_gb_node, char *&ref_name, GB_HASH *organism_hash), GB_HASH *organism_hash) {
1594    if (node->is_leaf) {
1595        relinker(node->gb_node, node->name, organism_hash);
1596    }
1597    else {
1598        relink_tree_rek(node->get_leftson(), relinker, organism_hash);
1599        relink_tree_rek(node->get_rightson(), relinker, organism_hash);
1600    }
1601}
1602
1603void AP_tree::relink_tree(GBDATA *gb_main, void (*relinker)(GBDATA *&ref_gb_node, char *&ref_name, GB_HASH *organism_hash), GB_HASH *organism_hash) {
1604    // relinks the tree using a relinker-function
1605    // every node in tree is passed to relinker, relinker might modify
1606    // these values (ref_gb_node and ref_name) and the modified values are written back into tree
1607
1608    GB_transaction  ta(gb_main);
1609    relink_tree_rek(this, relinker, organism_hash);
1610}
1611
1612
1613void AP_tree::reset_child_angles() {
1614    if (!is_leaf) {
1615        gr.reset_both_child_angles();
1616        get_leftson()->reset_child_angles();
1617        get_rightson()->reset_child_angles();
1618    }
1619}
1620
1621void AP_tree::reset_child_linewidths() {
1622    if (!is_leaf) {
1623        gr.reset_both_child_linewidths();
1624        get_leftson()->reset_child_linewidths();
1625        get_rightson()->reset_child_linewidths();
1626    }
1627}
1628
1629void AP_tree::set_linewidth_recursive(int width) {
1630    set_linewidth(width);
1631    if (!is_leaf) {
1632        get_leftson()->set_linewidth_recursive(width);
1633        get_rightson()->set_linewidth_recursive(width);
1634    }
1635}
1636
1637void AP_tree::reset_child_layout() {
1638    if (!is_leaf) {
1639        gr.reset_child_spread();
1640        gr.reset_both_child_angles();
1641        gr.reset_both_child_linewidths();
1642        get_leftson()->reset_child_layout();
1643        get_rightson()->reset_child_layout();
1644    }
1645}
1646
1647void AP_tree::reset_subtree_spreads() {
1648    gr.reset_child_spread();
1649    if (!is_leaf) {
1650        get_leftson()->reset_subtree_spreads();
1651        get_rightson()->reset_subtree_spreads();
1652    }
1653}
1654void AP_tree::reset_subtree_angles() {
1655    reset_angle();
1656    if (!is_leaf) reset_child_angles();
1657}
1658void AP_tree::reset_subtree_linewidths() {
1659    reset_linewidth();
1660    if (!is_leaf) reset_child_linewidths();
1661}
1662void AP_tree::reset_subtree_layout() {
1663    reset_linewidth();
1664    reset_angle();
1665    if (!is_leaf) reset_child_layout();
1666}
1667
1668bool AP_tree::is_inside_folded_group() const {
1669    if (gr.grouped) return true;
1670    if (!father) return false;
1671    return get_father()->is_inside_folded_group();
1672}
1673
Note: See TracBrowser for help on using the repository browser.