//------------------------------------------------------------------------------ // This code needs Tree to be a friend of Node void Tree::copyTraverse (NodePtr p1, NodePtr &p2) const { if (p1) { p2 = NewNode (); p1->Copy (p2); // Note the call to p2->child, not p2->GetChild(). Calling the field // is essential because calling GetChild merely passes a temporary // copy of the child, hence we are not actually creating a child of p2. // We can access child directly by making Tree a friend of Node (see // TreeLib.h). copyTraverse (p1->GetChild(), p2->Child); if (p2->GetChild()) p2->GetChild()->SetAnc (p2); // Ensure we don't copy RootedAt sibling. If the sibling is NULL then // we won't anyway, but this line ensures this for all cases. if (p1 != CurNode) copyTraverse (p1->GetSibling(), p2->Sib); // note sib if (p2->GetChild ()) { NodePtr q = p2->GetChild()->GetSibling(); while (q) { q->SetAnc (p2); q = q->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); } } } }
//------------------------------------------------------------------------------ void Tree::makeNodeList (NodePtr p) { if (p) { makeNodeList (p->GetChild ()); makeNodeList (p->GetSibling ()); if (p->IsLeaf()) { int leafnumberposition=p->GetLeafNumber()-1;//modified by BCO string plabel=p->GetLabel(); //modified by BCO LeafList[plabel] = leafnumberposition; //modified by BCO assert((Leaves+Internals)>leafnumberposition); Nodes[leafnumberposition] = p; //modified by BCO p->SetIndex (leafnumberposition); //modified by BCO } else { Nodes[count] = p; p->SetIndex (count); count++; } if (p != Root) { } } }
//------------------------------------------------------------------------------ // 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(); } } }
//------------------------------------------------------------------------------ // 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 Tree::deletetraverse (NodePtr p) { if (p) { deletetraverse (p->GetChild()); deletetraverse (p->GetSibling()); delete p; } }
//------------------------------------------------------------------------------ void Tree::markNodes(NodePtr p, bool on) { if (p) { p->SetMarked (on); markNodes (p->GetChild(), on); markNodes (p->GetSibling(), on); } }
//------------------------------------------------------------------------------ void Tree::getNodeHeights(NodePtr p) { if (p) { p->SetHeight (Leaves - p->GetWeight ()); if (p->GetHeight() > MaxHeight) MaxHeight = p->GetHeight(); getNodeHeights (p->GetChild()); getNodeHeights (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] = ' '; } }
//------------------------------------------------------------------------------ // Compute node depth (i.e, height above root). Based on COMPONENT 2.0 code, // assumes count is set to 0 prior to calling code void Tree::getNodeDepth(NodePtr p) { if (p) { p->SetDepth (count); count++; getNodeDepth (p->GetChild()); count--; getNodeDepth (p->GetSibling()); } }
//------------------------------------------------------------------------------ void Tree::drawAsTextTraverse (NodePtr p) { if (p) { drawAsTextTraverse (p->GetChild ()); if (p->IsLeaf ()) drawPendantEdge (p); if (p->GetSibling ()) drawInteriorEdge (p); drawAsTextTraverse (p->GetSibling ()); } }
//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()); } }
//------------------------------------------------------------------------------ // 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 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()); } }
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; } }