//------------------------------------------------------------------------------ // Fill in weight, degree, etc. void Tree::buildtraverse (NodePtr p) { if (p) { p->SetWeight (0); /*p->SetModelCategory(vector<double>(1,1.0)); //added by BCO p->SetStateOrder(vector<int>(1,0)); //Added by BCO p->SetStateTimes(vector<double>(1,0.0)); //Added by BCO*/ p->SetDegree (0); buildtraverse (p->GetChild ()); buildtraverse (p->GetSibling ()); if (p->IsLeaf()) { Leaves++; p->SetWeight (1); /*p->SetModelCategory(vector<double>(1,1.0)); //Added by BCO p->SetStateOrder(vector<int>(1,0)); //Added by BCO p->SetStateTimes(vector<double>(1,0.0)); //Added by BCO*/ } else { Internals++; } if (p != Root) { p->GetAnc()->AddWeight (p->GetWeight()); p->GetAnc()->IncrementDegree(); } } }
//Added by BCO //------------------------------------------------------------------------------ void Tree::traversenoquote (NodePtr p) { if (p) { if (p->IsLeaf()) { for (int i=0; i<(NEXUSString (p->GetLabel())).length(); i++) { if ((NEXUSString (p->GetLabel()))[i]!= '\'') { *treeStream <<(NEXUSString (p->GetLabel()))[i]; } } //*treeStream<<NEXUSString (p->GetLabel()); if (EdgeLengths) { *treeStream << ':' << p->GetEdgeLength (); } } else { *treeStream << "("; } traversenoquote (p->GetChild()); if (p->GetSibling()) { *treeStream << ","; } else { if (p != Root) { *treeStream << ")"; // 29/3/96 if ((p->GetAnc()->GetLabel() != "") && InternalLabels) { *treeStream << NEXUSString (p->GetAnc()->GetLabel ()) ; //here's the change from traverse } if (EdgeLengths && (p->GetAnc () != Root)) { *treeStream << ':' << p->GetAnc()->GetEdgeLength (); } } } traversenoquote (p->GetSibling()); } }
//------------------------------------------------------------------------------ void TreeOrder::SortDescendants (NodePtr node) { NodePtr head = node->GetChild (); NodePtr tail = head; while (tail->GetSibling () != NULL) { NodePtr p = tail->GetSibling (); if (MustSwap (head, p)) { tail->SetSibling (p->GetSibling ()); p->SetSibling (head); head = p; p->GetAnc()->SetChild (p); } else { NodePtr q = head; NodePtr r = q->GetSibling (); while (MustSwap (p, r)) { q = r; r = q->GetSibling (); } if (p == r) tail = p; else { tail->SetSibling (p->GetSibling ()); p->SetSibling (r); q->SetSibling (p); } } } }
//------------------------------------------------------------------------------ // Add Node below Below. Doesn't update any clusters, weights, etc. void Tree::AddNodeBelow (NodePtr Node, NodePtr Below) { NodePtr Ancestor = NewNode (); Ancestor->SetChild (Node); Node->SetAnc (Ancestor); NodePtr q = Below->GetAnc (); Internals++; if (Node->IsLeaf()) Leaves++; if (q == NULL || Below == q->GetChild()) { Node->SetSibling (Below); Ancestor->SetAnc (q); Ancestor->SetSibling (Below->GetSibling()); Below->SetSibling (NULL); Below->SetAnc (Ancestor); if (q == NULL) Root = Ancestor; else q->SetChild (Ancestor); } else { // Get left sibling of Below NodePtr r = Below->LeftSiblingOf(); while (Below != r->GetSibling()) r = r->GetSibling(); Node->SetSibling (Below); Ancestor->SetAnc (q); Ancestor->SetSibling (Below->GetSibling()); Below->SetSibling (NULL); Below->SetAnc (Ancestor); r->SetSibling (Ancestor); } }
//------------------------------------------------------------------------------ void RectangleTreeDrawer::CalcCoordinates () { t->MakeNodeList(); maxDepth = 0; // Clear internal node depths for (int i = t->GetNumLeaves(); i < t->GetNumNodes(); i++) { (*t)[i]->SetDepth(0); } for (int i = 0; i < t->GetNumLeaves(); i++) { NodePtr p = (*t)[i]->GetAnc(); int count = 1; while (p) { if (count > p->GetDepth()) { p->SetDepth(count); if (count > maxDepth) maxDepth = count; } count++; p = p->GetAnc(); } } double l = t->GetNumLeaves(); leafGap = height / (l - 1.0); l = maxDepth + 1.0; if (rooted) nodeGap = width / l; else nodeGap = width / (l - 1.0); leafCount = 0; if (rooted) { // Allow for edge below root left += nodeGap; width -= nodeGap; } NodeIterator <Node> n (t->GetRoot()); Node *q = n.begin(); while (q) { if (q->IsLeaf ()) { CalcLeaf (q); } else { CalcInternal (q); } q = n.next(); } }
//------------------------------------------------------------------------------ void Tree::traverse (NodePtr p) { if (p) { if (p->IsLeaf()) { *treeStream << NEXUSString (p->GetLabel()); if (EdgeLengths) { *treeStream << ':' << p->GetEdgeLength (); } } else { *treeStream << "("; } traverse (p->GetChild()); if (p->GetSibling()) { *treeStream << ","; } else { if (p != Root) { *treeStream << ")"; // 29/3/96 if ((p->GetAnc()->GetLabel() != "") && InternalLabels) { *treeStream << '\'' << NEXUSString (p->GetAnc()->GetLabel ()) << '\''; } if (EdgeLengths && (p->GetAnc () != Root)) { *treeStream << ':' << p->GetAnc()->GetEdgeLength (); } } } traverse (p->GetSibling()); } }
//------------------------------------------------------------------------------ void Tree::drawPendantEdge (NodePtr p) { NodePtr q = p->GetAnc(); if (q == NULL) { // Handle the degenerate case of a tree with a single leaf Line = (char) HBAR; drawLine (p); } else { int start = q->GetHeight(); int stop = p->GetHeight(); char symbol; // Draw line between p and its ancestor int i; for (i = start + 1; i <= stop; i++) Line[i] = (char)HBAR; // € // Find appropriate symbol for link to ancestor if (p == q->GetChild()) { symbol = (char)LEFT; // ò } else { // p is a sibling if (p->GetSibling()) symbol = (char)SIB; // Ì else symbol = (char)RIGHT; // Ë } Line[start] = symbol; // Fill in ancestors fillInAncestors (p); // Terminate line Line[stop + 1] = '\0'; drawLine (p); /* // Output line and taxon name *treeStream << Line.c_str() << " " << p->GetLabel () // << "h=" << p->GetHeight() << " w= " // << p->GetWeight() <<endl; */ // Clear the line for the next pass for (i = 0; i < (Leaves + 2); i++) // to do: get a better limit for this Line[i] = ' '; } }
//------------------------------------------------------------------------------ void Tree::fillInAncestors (NodePtr p) { NodePtr q = p->GetAnc (); NodePtr r = p; while (q != Root) { if ( (q->GetSibling () && !(r->IsTheChild ())) || (!(q->IsTheChild ()) && r->IsTheChild()) ) { if (r ==p && q->GetHeight() == q->GetAnc()->GetHeight()) Line[q->GetAnc()->GetHeight()] = SIB; else Line[q->GetAnc()->GetHeight()] = VBAR; } r = q; q = q->GetAnc (); } }
//------------------------------------------------------------------------------ // Compute nodal heights based on path length from root, and store maximum // value in plot.maxheight. Used by drawing routines. void Tree::getPathLengths (NodePtr p) { if (p) { if (p != Root) { float l = p->GetEdgeLength(); if (l < 0.000001) // suppress negative branch lengths l = 0.0; p->SetPathLength (p->GetAnc()->GetPathLength() + l); } if (p->GetPathLength() > MaxPathLength) MaxPathLength = p->GetPathLength(); getPathLengths (p->GetChild()); getPathLengths (p->GetSibling()); } }
//------------------------------------------------------------------------------ void CircleTreeDrawer::CalcCoordinates () { t->MakeNodeList(); maxDepth = 0; // Clear internal node depths for (int i = t->GetNumLeaves(); i < t->GetNumNodes(); i++) { (*t)[i]->SetDepth(0); } for (int i = 0; i < t->GetNumLeaves(); i++) { NodePtr p = (*t)[i]->GetAnc(); int count = 1; while (p) { if (count > p->GetDepth()) { p->SetDepth(count); if (count > maxDepth) maxDepth = count; } count++; p = p->GetAnc(); } } leaf_angle = 2 * M_PI / t->GetNumLeaves(); left = top = 0.0; width = height = 400.0; leaf_radius = width / 2.0; leafCount = 0; nodeGap = leaf_radius / double(maxDepth); origin.x = 0.0; origin.y = 0.0; NodeIterator <Node> n (t->GetRoot()); Node *q = n.begin(); while (q) { if (q->IsLeaf ()) { CalcLeaf (q); } else { CalcInternal (q); } q = n.next(); } // Translate origin.x = left + (width/2.0); origin.y = top + (height/2.0); q = n.begin(); while (q) { node_coordinates[q].x += origin.x; node_coordinates[q].y += origin.y; node_backarc[q].x += origin.x; node_backarc[q].y += origin.y; q = n.next(); } }
//------------------------------------------------------------------------------ void Tree::drawInteriorEdge (NodePtr p) { NodePtr r = p->GetAnc (); int stop = r->GetHeight(); if (p->IsTheChild ()) { // Visiting ancestor for the first time, so draw the // end symbol if (r == Root) { // if (IsRooted ()) Line[stop] = TEE; // « // else // Line[stop] = VBAR; // Ò } else { Line[stop] = TEE; // « } // Draw branch itself if (r != Root) { // Line int start = r->GetAnc()->GetHeight(); for (int i = start + 1; i < stop; i++) { Line[i] = HBAR; // € } // Start symbol if (start == stop) Line[start] = VBAR; // Ò else if (r->IsTheChild ()) Line[start] = LEFT; // ò else if (r->GetSibling ()) Line[start] = SIB; // Ì else Line[start] = RIGHT; // Ë // fillInAncestors (r); } } else { // Just draw nodes below Line[stop] = VBAR; fillInAncestors (p->GetSibling()); } // Output the line Line[stop + 1] = '\0'; drawLine (r, p->IsTheChild()); /* *treeStream << Line.c_str(); // *treeStream << "h=" << r->GetHeight() << " w= " // << r->GetWeight() << "-- "; // Draw internal label, if present string s = r->GetLabel(); if (s != "" && p->IsTheChild ()) *treeStream << r->GetLabel(); *treeStream << endl; */ // Clear the line for the next pass for (int i = 0; i < (Leaves + 2); i++) // to do: get a better limit Line[i] = ' '; }
NodePtr Tree::RemoveNode (NodePtr Node) { NodePtr result = NULL; if (Node == Root) { if (Leaves == 1) { Root = NULL; Node->SetAnc (NULL); Leaves = Internals = 0; } return result; } NodePtr p; NodePtr Ancestor = Node->GetAnc(); if (Ancestor->GetDegree() == 2) { // ancestor is binary, so remove node and its ancestor if (Node->IsTheChild ()) p = Node->GetSibling(); else p = Ancestor->GetChild(); NodePtr q = Ancestor->GetAnc(); p->SetAnc (q); if (q != NULL) { if (Ancestor->IsTheChild()) q->SetChild (p); else { NodePtr r = Ancestor->LeftSiblingOf (); r->SetSibling (p); } p->SetSibling (Ancestor->GetSibling()); result = p; } else { // Ancestor is the root Root = p; p->SetSibling (NULL); result = p; } delete Ancestor; Internals--; if (Node->IsLeaf()) Leaves--; Node->SetAnc (NULL); Node->SetSibling (NULL); } else { // polytomy, just remove node NodePtr q; if (Node->IsTheChild()) { Ancestor->SetChild (Node->GetSibling()); q = Node->GetSibling (); } else { q = Node->LeftSiblingOf (); q->SetSibling (Node->GetSibling ()); } Node->SetSibling (NULL); Node->SetAnc (NULL); if (Node->IsLeaf()) Leaves--; Ancestor->SetDegree (Ancestor->GetDegree() - 1); result = q; } }