void Tree::RootAt(PolyNode* inNode) { double lengthbefore = GetLength(); // inNode should not be root if (inNode->IsRoot()) { cerr << "error in PolyNode::RootAt : inNode is root\n"; exit(1); } if (inNode) { PolyNode* theUp = inNode->Up(); PolyNode* newRoot = 0; if (theUp->IsRoot()) { inNode->Detach(); if (theUp->down->next != theUp->down) { newRoot = new PolyNode(); newRoot->SetTree(this); theUp->AttachTo(newRoot); theUp->mProb = inNode->mProb; } else { newRoot = theUp; } } else { newRoot = theUp->FlipFlop(); if ( ! newRoot) { newRoot = new PolyNode(); newRoot->SetTree(this); } inNode->Detach(); theUp->AttachTo(newRoot); theUp->mProb = inNode->mProb; } inNode->AttachTo(newRoot); mRoot = newRoot; } double lengthafter = GetLength(); if (fabs(lengthafter - lengthbefore) > 1e-8) { cerr << "error in rerooting: length not conserved\n"; cerr << "length before : " << lengthbefore << '\n'; cerr << "length after : " << lengthafter << '\n'; cerr << lengthbefore - lengthafter << '\n'; // exit(1); } double totallength = mRoot->down->branchLength + mRoot->down->next->branchLength; mRoot->down->branchLength = totallength / 2; mRoot->down->next->branchLength = totallength / 2; }
void Tree::Trichotomise() { double lengthbefore = GetLength(); PolyNode* node = mRoot->down; if (node->next->next == node) { if (!node->IsLeaf()) { node = node->next; } else { if (node->next->IsLeaf()) { cerr << "error : cannot trichotomise a two species tree\n"; exit(1); } } PolyNode* temp = node->next; node->Detach(); // PolyNode* temp = mRoot->down; mRoot->down = 0; // delete mRoot; mRoot = temp; mRoot->up = 0; node->branchLength += mRoot->branchLength; mRoot->branchLength = 0; node->AttachTo(mRoot); } double lengthafter = GetLength(); if (fabs(lengthafter - lengthbefore) > 1e-8) { cerr << "error in trichotomise: length not conserved\n"; cerr << "length before : " << lengthbefore << '\n'; cerr << "length after : " << lengthafter << '\n'; cerr << lengthbefore - lengthafter << '\n'; exit(1); } }
int Tree::ReadPhylip(istream& is, PolyNode* currentNode) { // int verbose = 1; PolyNode* node = 0; double d; int END = 0; char c = is.peek(); while ((c == ' ') || (c == '\n') || (c == '\t')) { is.get(); c = is.peek(); } while( (! is.eof()) && (! END) ) { string s; char c = is.peek(); // cerr << c ; switch (c) { case '\n' : case ' ' : case '\t' : is >> c; if (verbose) { cerr << c; } break; case '(' : is >> c; if (verbose) { cerr << c; } // make a new polynode node = new PolyNode(); node->AttachTo(currentNode); currentNode = node; break; case ',' : is >> c; if (verbose) { cerr << c; } node = new PolyNode(); if (currentNode->IsRoot()) { cerr << "error in reading tree file : found a coma not within brackets\n"; exit(1); } node->AttachTo(currentNode->Up()); currentNode = node; break; case ')' : is >> c; if (verbose) { cerr << c; } if (currentNode->IsRoot()) { cerr << "error in reading tree file: found more closing than opening brackets\n"; exit(1); } currentNode = currentNode->Up(); // check whether is followed by a digit, a ':', a ')' or a ',' (anything else will throw exception) c = is.peek(); switch(c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': // probability is >> d; if (verbose) { cerr << d; } currentNode->SetProb(d); // then check whether is further followed by ':' or ',' or ')' (anything else exits) c = is.peek(); switch(c) { case ':' : is >> c; if (verbose) { cerr << c; } // read branchLength // and check that it is followed either by ',' or by ')' is >> d; if (verbose) { cerr << "BL" << d; } currentNode->SetBranchLength(d); c = is.peek(); if ((c != ',') && (c != ')') && (c != ';')) { cerr << "error\n"; cerr << c << '\n'; exit(1); } break; case ',' : case ')' : break; default : cerr << "error in reading tree file : after reading a branchlength of an internal node\n"; cerr << c << '\n'; double d; is >> d; cerr << d << '\n'; exit(1); break; } break; case ':' : is >> c; if (verbose) { cerr << c; } // read branchLength // and check that it is followed either by ',' or by ')' is >> d; if (verbose) { cerr << "BL" << d; } currentNode->SetBranchLength(d); c = is.peek(); if ((c != ',') && (c != ')') && (c != ';')) { cerr << "error\n"; cerr << c << '\n'; exit(1); } break; case ';' : case ',' : case ')' : break; default : cerr << "error in reading tree file\n"; cerr << "character : " << c << '\n'; exit(1); break; } break; case ';' : is >> c; if (verbose) { cerr << "END" << c; } // close the tree // current node should be root if (! currentNode->IsRoot()) { cerr << "error in reading tree file : lacking closing brackets overall\n"; exit(1); } END = 1; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': // species label s == ""; do { s += c; is >> c; if (is.eof()) { cerr << "error in reading treefile : unexpected end of file in string\n"; exit(1); } c = is.peek(); } while ((c != ',') && (c != ':') && (c != ')')); if (IsInt(s)) { int i = Int(s); // is >> i; if (verbose) { cerr << i; } node->SetLabel(i); } else { node->SetName(s); } // check whether is followed by : or , or ) (anything else will throw exception) c = is.peek(); switch(c) { case ':' : is >> c; if (verbose) { cerr << c; } // branchlength double d; is >> d; if (verbose) { cerr << "BL" << d; } node->SetBranchLength(d); c = is.peek(); if ((c != ',') && (c != ')')) { cerr << "error\n"; cerr << c << '\n'; exit(1); } break; case ',' : case ')' : break; default : cerr << "error in reading tree file\n"; cerr << "character : " << c << '\n'; exit(1); break; } break; default : // assume this is a species name s == ""; do { s += c; is >> c; if (is.eof()) { return 0; } c = is.peek(); } while ((c != ',') && (c != ':') && (c != ')')); currentNode->SetName(s); if (verbose) { cerr << '\"' << s << '\"'; } // check whether is followed by : or , (anything else will throw exception) c = is.peek(); switch(c) { case ':' : is >> c; if (verbose) { cerr << c; } // branchlength double d; is >> d; if (verbose) { cerr << "BL" << d; } node->SetBranchLength(d); break; case ',' : case ')': break; default : cerr << "error in reading tree file : after reading species name\n"; exit(1); break; } break; } } if (verbose) { cerr << "tree read : ok " << '\n' << '\n'; cerr.flush(); } return 1; }