23 deleteWithNodes =
false;
40 #if defined(PROVIDE_TREE_STRUCTURE_TESTS)
42 Validity TreeNode::is_valid()
const {
53 if (valid) valid = get_rightson()->is_valid();
54 if (valid) valid = get_leftson()->is_valid();
58 if (valid) valid =
Validity(troot->get_root_node()->is_ancestor_of(
this),
"root is not nodes ancestor");
62 if (valid) valid =
Validity(troot->get_root_node() ==
this,
"node has no father, but isn't root-node");
72 if (
rightson) valid = get_rightson()->is_valid();
73 if (
leftson && valid) valid = get_leftson()->is_valid();
82 #endif // PROVIDE_TREE_STRUCTURE_TESTS
85 if (tree_root != new_root) {
87 if (
leftson) get_leftson()->set_tree_root(new_root);
88 if (
rightson) get_rightson()->set_tree_root(new_root);
92 void TreeNode::reorder_subtree(
TreeOrder mode) {
93 static const char *smallest_leafname;
96 smallest_leafname =
name;
99 int leftsize = get_leftson() ->get_leaf_count();
100 int rightsize = get_rightson()->get_leaf_count();
103 bool big_at_top = leftsize>rightsize;
104 bool big_at_bottom = leftsize<rightsize;
105 bool swap_branches = (mode&
ORDER_BIG_DOWN) ? big_at_top : big_at_bottom;
129 get_leftson()->reorder_subtree(lmode);
130 const char *leftleafname = smallest_leafname;
132 get_rightson()->reorder_subtree(rmode);
133 const char *rightleafname = smallest_leafname;
135 if (leftleafname && rightleafname) {
136 int name_cmp = strcmp(leftleafname, rightleafname);
138 smallest_leafname = leftleafname;
141 smallest_leafname = rightleafname;
142 if (leftsize == rightsize) {
143 const char *smallest_leafname_save = smallest_leafname;
146 get_leftson ()->reorder_subtree(lmode);
rt_assert(strcmp(smallest_leafname, rightleafname)== 0);
147 get_rightson()->reorder_subtree(rmode);
rt_assert(strcmp(smallest_leafname, leftleafname) == 0);
149 smallest_leafname = smallest_leafname_save;
161 reorder_subtree(mode);
167 get_leftson()->rotate_subtree();
168 get_rightson()->rotate_subtree();
184 if (inverseLeft) keeledOver =
false;
196 if (!inverseLeft) keeledOver =
false;
216 TreeNode *old_brother =
is_inside(old_root->get_leftson()) ? old_root->get_rightson() : old_root->get_leftson();
223 SmartCharPtr remarkPtr;
253 pntr->keelOver(prev, next, len);
257 next = next->get_father();
265 pntr->keelOver(prev, old_brother, old_root_len);
267 old_brother->
father = pntr;
277 if (
name && strcmp(
name, wantedName) == 0) found =
this;
281 if (!found) found = get_rightson()->
findLeafNamed(wantedName);
291 enum { NLD_NODIST = 0, NLD_DOWNDIST, NLD_BOTHDIST } state;
303 if (state < NLD_DOWNDIST) state = NLD_DOWNDIST;
309 if (state < NLD_BOTHDIST) state = NLD_BOTHDIST;
316 std::map<TreeNode*, NodeLeafDistance> data;
325 data[node].set_downdist(0.0);
328 insert_tree(node->get_leftson());
329 insert_tree(node->get_rightson());
331 data[node].set_downdist(
std::max(data[node->get_leftson()].get_downdist()+node->
leftlen,
332 data[node->get_rightson()].get_downdist()+node->
rightlen));
336 void findBetterEdge_sub(
TreeNode *node) {
343 GBT_LEN upDist =
std::max(data[father].get_updist(), data[brother].get_downdist()+brothLen);
344 GBT_LEN downDist = data[node].get_downdist();
347 GBT_LEN edge_dd = calc_distdiff(upDist, downDist);
348 if (edge_dd<min_distdiff) {
350 min_distdiff = edge_dd;
354 data[node].set_updist(upDist+len);
357 findBetterEdge_sub(node->get_leftson());
358 findBetterEdge_sub(node->get_rightson());
362 void findBetterEdge(
TreeNode *node) {
364 findBetterEdge_sub(node->get_leftson());
365 findBetterEdge_sub(node->get_rightson());
371 : innermost(rootNode->get_leftson(), rootNode->get_rightson())
373 insert_tree(rootNode);
375 TreeNode *lson = rootNode->get_leftson();
376 TreeNode *rson = rootNode->get_rightson();
380 GBT_LEN lddist = data[lson].get_downdist();
381 GBT_LEN rddist = data[rson].get_downdist();
383 data[lson].set_updist(rddist+rootEdgeLen);
384 data[rson].set_updist(lddist+rootEdgeLen);
386 min_distdiff = calc_distdiff(lddist, rddist);
388 findBetterEdge(lson);
389 findBetterEdge(rson);
404 typedef std::map<TreeNode*,GBT_LEN> LengthMap;
405 typedef std::set<TreeNode*> NodeSet;
407 LengthMap eliminatedParentLength;
408 LengthMap addedParentLength;
418 addedParentLength[node] += addLen;
425 if (useProgress) progress =
new arb_progress(
"Distributing eliminated lengths", eliminatedParentLength.size());
427 while (!eliminatedParentLength.empty()) {
428 for (LengthMap::iterator from = eliminatedParentLength.begin(); from != eliminatedParentLength.end(); ++from) {
430 GBT_LEN elimLen = from->second;
433 if (progress) ++*progress;
435 eliminatedParentLength.clear();
443 for (LengthMap::iterator to = addedParentLength.begin(); to != addedParentLength.end(); ++to) {
445 GBT_LEN additionalLen = to->second;
446 double effective_length = affectedEdge.
length() + additionalLen;
448 if (effective_length<=0.0) {
451 handled.insert(to->first);
455 if (progress && !eliminatedParentLength.empty()) {
462 for (NodeSet::iterator del = handled.begin(); del != handled.end(); ++del) {
463 addedParentLength.erase(*del);
468 for (LengthMap::iterator to = addedParentLength.begin(); to != addedParentLength.end(); ++to) {
470 GBT_LEN additionalLen = to->second;
471 double effective_length = affectedEdge.
length() + additionalLen;
476 if (progress)
delete progress;
480 GBT_LEN ARB_edge::adjacent_distance()
const {
484 return next().length_or_adjacent_distance() +
counter_next().length_or_adjacent_distance();
493 if (len != 0.0) virtually_distribute_length_forward(len, collect);
511 GBT_LEN d1 = e1.length_or_adjacent_distance();
512 GBT_LEN d2 = e2.length_or_adjacent_distance();
516 e1.virtually_add_or_distribute_length_forward(len*d1, collect);
517 e2.virtually_add_or_distribute_length_forward(len*d2, collect);
534 GBT_LEN dist_fwd = adjacent_distance();
535 GBT_LEN dist_bwd = backEdge.adjacent_distance();
536 GBT_LEN lenW = len/(dist_fwd+dist_bwd);
537 len_fwd = lenW*dist_fwd;
538 len_bwd = lenW*dist_bwd;
542 if (
is_normal(len_fwd)) virtually_distribute_length_forward(len_fwd, collect);
543 if (
is_normal(len_bwd)) backEdge.virtually_distribute_length_forward(len_bwd, collect);
546 void TreeNode::eliminate_and_collect(
const multifurc_limits& below, LengthCollector& collect) {
551 if (!
is_leaf() || below.applyAtLeafs) {
564 collect.eliminate_parent_edge(
this);
573 get_leftson() ->eliminate_and_collect(below, collect);
574 get_rightson()->eliminate_and_collect(below, collect);
604 GBT_LEN change = new_len-old_len;
616 #if defined(ASSERTION_USED)
634 progress.
subtitle(
"Collecting branches to eliminate");
635 root->get_leftson()->eliminate_and_collect(below, collector);
636 root->get_rightson()->eliminate_and_collect(below, collector);
645 remark_branch.setNull();
647 get_leftson()->remove_bootstrap();
648 get_rightson()->remove_bootstrap();
661 freeset(new_remark,
GBS_trim(new_remark));
662 if (!new_remark[0]) {
664 remark_branch.setNull();
667 remark_branch = new_remark;
672 if (!error) error = get_leftson()->apply_aci_to_remarks(aci, callEnv);
673 if (!error) error = get_rightson()->apply_aci_to_remarks(aci, callEnv);
682 get_leftson()->reset_branchlengths();
683 get_rightson()->reset_branchlengths();
692 get_leftson()->scale_branchlengths(factor);
693 get_rightson()->scale_branchlengths(factor);
702 get_leftson()->sum_child_lengths() +
703 get_rightson()->sum_child_lengths();
717 double len = bootstrap/100.0;
724 get_leftson()->bootstrap2branchlen();
725 get_rightson()->bootstrap2branchlen();
736 get_leftson()->branchlen2bootstrap();
737 get_rightson()->branchlen2bootstrap();
739 #if defined(ASSERTION_USED)
752 result = get_leftson();
759 result = get_rightson();
793 if (
this == other)
return this;
796 return get_father()->ancestor_common_with(other->get_father());
801 return get_leftson()->count_clades() + get_rightson()->count_clades() +
is_clade();
804 #if defined(ASSERTION_USED) || defined(PROVIDE_TREE_STRUCTURE_TESTS)
822 void TEST_tree_iterator() {
855 if (edge.is_edge_to_leaf()) ++count_leafs;
857 while (edge != start);
870 if (edge.is_edge_to_leaf()) ++count_leafs;
872 while (edge != start);
884 void TEST_tree_branch_modifications() {
888 const char *left_newick =
"((((((CloTyro3:1.046,CloTyro4:0.061)'40%':0.026,CloTyro2:0.017)'0%':0.017,CloTyrob:0.009)'97%':0.274,CloInnoc:0.371)'0%':0.057,CloBifer:0.388)'53%':0.124,(((CloButy2:0.009,CloButyr:0.000):0.564,CloCarni:0.120)'33%':0.010,CloPaste:0.179)'97%':0.131):0.081;";
889 const char *left_newick_bs2bl =
"((((((CloTyro3:0.100,CloTyro4:0.100):0.400,CloTyro2:0.100):0.000,CloTyrob:0.100):0.970,CloInnoc:0.100):0.000,CloBifer:0.100):0.530,(((CloButy2:0.100,CloButyr:0.100):1.000,CloCarni:0.100):0.330,CloPaste:0.100):0.970):0.500;";
891 const char *right_newick =
"((((CorAquat:0.084,CurCitre:0.058):0.103,CorGluta:0.522)'17%':0.053,CelBiazo:0.059)'40%':0.207,CytAquat:0.711):0.081;";
892 const char *right_newick_preserved1 =
"((((CorAquat:0.084,CurCitre:0.058):0.103,CorGluta:0.522)'17%':0.060,CelBiazo:0.029)'40%':0.231,CytAquat:0.711):0.081;";
893 const char *right_newick_preserved2 =
"((((CorAquat:0.084,CurCitre:0.058):0.103,CorGluta:0.522)'17%':0.041,CelBiazo:0.117)'40%':0.161,CytAquat:0.711):0.081;";
894 const char *right_newick_bl2bs =
"((((CorAquat,CurCitre)'10%',CorGluta)'5%',CelBiazo)'21%',CytAquat)'100%';";
902 TreeNode *left = tree->get_leftson();
903 TreeNode *right = tree->get_rightson();
919 TreeNode *right = tree->get_rightson();
void set_bootstrap(double bootstrap)
void set_branchlength_unrooted(GBT_LEN newlen)
void set_updist(GBT_LEN UpDist)
size_t GBT_count_leafs(const TreeNode *tree)
GBDATA * GB_open(const char *path, const char *opent)
void virtually_distribute_length(GBT_LEN len, TreeNode::LengthCollector &collect) const
void bootstrap2branchlen()
GBT_RemarkType parse_bootstrap(double &bootstrap) const
#define implicated(hypothesis, conclusion)
TreeNode * findLeafNamed(const char *wantedName)
const TreeNode * get_root_node() const
GBT_LEN get_branchlength_unrooted() const
virtual void compute_tree()=0
POS_TREE1 * get_father() const
TreeRoot * get_tree_root() const
TreeNode * GBT_read_tree(GBDATA *gb_main, const char *tree_name, TreeRoot *troot)
#define DEFAULT_BRANCH_LENGTH
const char * GBS_global_string(const char *templat,...)
ARB_edge previous() const
ARB_edge rootEdge(TreeRoot *root)
void use_as_remark(const SmartCharPtr &newRemark)
int ARB_strNULLcmp(const char *s1, const char *s2)
void reset_branchlengths()
bool has_valid_root_remarks() const
static HelixNrInfo * start
ARB_edge parentEdge(TreeNode *son)
#define TEST_PUBLISH(testfunction)
POS_TREE1 * get_father() const
GB_ERROR GB_await_error()
void branchlen2bootstrap()
void add_parent_length(TreeNode *node, GBT_LEN addLen)
#define TEST_EXPECT(cond)
#define TEST_EXPECT_NEWICK(format, tree, expected_newick)
const TreeNode * ancestor_common_with(const TreeNode *other) const
CONSTEXPR_INLINE int leafs_2_edges(int leafs, TreeModel model)
char * GBS_trim(const char *str)
static void error(const char *msg)
bool is_root_node() const
CONSTEXPR_INLINE_Cxx14 void swap(unsigned char &c1, unsigned char &c2)
const ARB_edge & innermost_edge() const
EdgeFinder(TreeNode *rootNode)
void multifurcate_whole_tree(const multifurc_limits &below)
void set_downdist(GBT_LEN DownDist)
AP_tree_nlen * rootNode()
CONSTEXPR_INLINE bool valid(SpeciesCreationMode m)
void eliminate_parent_edge(TreeNode *node)
bool is_ancestor_of(const TreeNode *descendant) const
void reorder_tree(TreeOrder mode)
bool knownNonNull(const void *nonnull)
bool has_no_remark() const
bool is_edge_to_leaf() const
void set_branchlength_preserving(GBT_LEN new_len)
TreeNode * fixDeletedSon()
bool is_inside(const TreeNode *subtree) const
GBT_LEN get_updist() const
void subtitle(const char *stitle)
void scale_branchlengths(double factor)
void independent_distribution(bool useProgress)
void set_tree_root(TreeRoot *new_root)
GBT_LEN sum_child_lengths() const
ARB_edge counter_next() const
GBT_LEN get_downdist() const
GB_ERROR apply_aci_to_remarks(const char *aci, const GBL_call_env &callEnv)
ARB_edge find_innermost_edge()
NOT4PERL char * GB_command_interpreter_in_env(const char *str, const char *commands, const GBL_call_env &callEnv)
GBT_LEN get_branchlength() const
GB_transaction ta(gb_var)
void destroy(TreeNode *that)
virtual void change_root(TreeNode *old, TreeNode *newroot)
void set_length(GBT_LEN len)
const char * get_remark() const
const SmartCharPtr & get_remark_ptr() const
#define TEST_EXPECT_EQUAL(expr, want)
void GB_close(GBDATA *gbd)
static int iteration_count(int leafs_in_tree)