bool sameTreeTolopogy(tree t1, tree t2){ if (t1.getNodesNum() != t2.getNodesNum()) { errorMsg::reportError("error in function same tree topology (1)"); } tree::nodeP x = t2.getRoot(); while (x->getNumberOfSons() > 0) x= x->getSon(0); t1.rootAt(t1.findNodeByName(x->name())->father()); // now they have the same root t2.rootAt(t2.findNodeByName(x->name())->father()); // now they have the same root map<int,string> names1; treeIterDownTopConst tit1(t1); for (tree::nodeP nodeM = tit1.first(); nodeM != tit1.end(); nodeM = tit1.next()) { vector<string> nameOfChild; for (int i=0; i < nodeM->getNumberOfSons();++i) { nameOfChild.push_back(names1[nodeM->getSon(i)->id()]); } if (nodeM->getNumberOfSons()==0) nameOfChild.push_back(nodeM->name()); sort(nameOfChild.begin(),nameOfChild.end()); string res = "("; for (int k=0; k < nameOfChild.size(); ++k) { res += nameOfChild[k]; } res += ")"; names1[nodeM->id()] = res; } map<int,string> names2; treeIterDownTopConst tit2(t2); for (tree::nodeP nodeM2 = tit2.first(); nodeM2 != tit2.end(); nodeM2 = tit2.next()) { vector<string> nameOfChild; for (int i=0; i < nodeM2->getNumberOfSons();++i) { nameOfChild.push_back(names2[nodeM2->getSon(i)->id()]); } if (nodeM2->getNumberOfSons()==0) nameOfChild.push_back(nodeM2->name()); sort(nameOfChild.begin(),nameOfChild.end()); string res = "("; for (int k=0; k < nameOfChild.size(); ++k) { res += nameOfChild[k]; } res += ")"; names2[nodeM2->id()] = res; } return names1[t1.getRoot()->id()] == names2[t2.getRoot()->id()]; }
// bigTree is passed by value and not by reference. Therefore, this method doens't change the original bigTree, // but allocates a new bigTree to be split. bool cutTreeToTwo(tree bigTree, const string& nameOfNodeToCut, tree &small1, tree &small2){// cutting above the NodeToCut. // we want to cut the tree in two. // first step: we make a new node between the two nodes that have to be splited, tree::nodeP node2splitOnNewTree = bigTree.findNodeByName(nameOfNodeToCut); string interNode = "interNode"; if (node2splitOnNewTree->father() == NULL) return(false); // assert(node2splitOnNewTree->father() != NULL); tree::nodeP tmp = makeNodeBetweenTwoNodes(bigTree,node2splitOnNewTree->father(),node2splitOnNewTree, interNode); bigTree.rootAt(tmp); // tmp is the interNode and it's now the root of the tree. Its sons are node2splitOnNewTree and its father. string allNodes = "Runs/testBifurcating/beforeCut.tree"; bigTree.output(allNodes, tree::PHYLIP, true); cutTreeToTwoSpecial(bigTree,tmp, small1,small2); if (small1.getNodesNum() < 5 || small2.getNodesNum() < 5) return (false); LOGDO(15,small1.output(myLog::LogFile(),tree::ANCESTORID)); LOGDO(15,small2.output(myLog::LogFile(),tree::ANCESTORID)); tree::nodeP toDel1 = small1.findNodeByName(interNode); small1.removeLeaf(toDel1); tree::nodeP toDel2 = small2.findNodeByName(interNode); small2.removeLeaf(toDel2); // this part fix the ids. treeIterTopDown tIt(small1); int newId =0; for (tree::nodeP mynode = tIt.first(); mynode != tIt.end(); mynode = tIt.next()) { mynode->setID(newId); newId++; } treeIterTopDown tIt2(small2); int newId2 =0; for (tree::nodeP mynode2 = tIt2.first(); mynode2 != tIt2.end(); mynode2 = tIt2.next()) { mynode2->setID(newId2); newId2++; } return (true); // successes! };