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