X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=tree.cpp;h=7da3cef3718502640d61377bccbaae0d8e4213d3;hb=30f2d98fffb579b870c8969ddcc1dfc61ccbb70a;hp=ee17e6f37f6417d24546697e3247c21f34d1d0aa;hpb=02909d6cae9963ba00dc746969a370fa8ca934fc;p=mothur.git diff --git a/tree.cpp b/tree.cpp index ee17e6f..7da3cef 100644 --- a/tree.cpp +++ b/tree.cpp @@ -14,9 +14,10 @@ Tree::Tree() { try { globaldata = GlobalData::getInstance(); + m = MothurOut::getInstance(); if (globaldata->runParse == true) { parseTreeFile(); globaldata->runParse = false; } - +//for(int i = 0; i < globaldata->Treenames.size(); i++) { cout << i << '\t' << globaldata->Treenames[i] << endl; } numLeaves = globaldata->Treenames.size(); numNodes = 2*numLeaves - 1; @@ -27,7 +28,8 @@ Tree::Tree() { //initialize leaf nodes if (i <= (numLeaves-1)) { tree[i].setName(globaldata->Treenames[i]); - tree[i].setGroup(globaldata->gTreemap->getGroup(globaldata->Treenames[i])); + vector tempGroups; tempGroups.push_back(globaldata->gTreemap->getGroup(globaldata->Treenames[i])); + tree[i].setGroup(tempGroups); //set pcount and pGroup for groupname to 1. tree[i].pcount[globaldata->gTreemap->getGroup(globaldata->Treenames[i])] = 1; tree[i].pGroups[globaldata->gTreemap->getGroup(globaldata->Treenames[i])] = 1; @@ -37,23 +39,107 @@ Tree::Tree() { //intialize non leaf nodes }else if (i > (numLeaves-1)) { tree[i].setName(""); - tree[i].setGroup(""); + vector tempGroups; + tree[i].setGroup(tempGroups); } } } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function Tree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "Tree"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function Tree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ Tree::~Tree() {} /*****************************************************************/ +void Tree::addNamesToCounts() { + try { + //ex. seq1 seq2,seq3,se4 + // seq1 = pasture + // seq2 = forest + // seq4 = pasture + // seq3 = ocean + + //before this function seq1.pcount = pasture -> 1 + //after seq1.pcount = pasture -> 2, forest -> 1, ocean -> 1 + + //before this function seq1.pgroups = pasture -> 1 + //after seq1.pgroups = pasture -> 1 since that is the dominant group + + + //go through each leaf and update its pcounts and pgroups + for (int i = 0; i < numLeaves; i++) { + string name = tree[i].getName(); + + map::iterator itNames = globaldata->names.find(name); + + if (itNames == globaldata->names.end()) { m->mothurOut(name + " is not in your name file, please correct."); m->mothurOutEndLine(); exit(1); } + else { + vector dupNames; + splitAtComma(globaldata->names[name], dupNames); + + map::iterator itCounts; + int maxPars = 1; + for (int j = 0; j < dupNames.size(); j++) { + + if (dupNames[j] != name) {//you already added yourself in the constructor + string group = globaldata->gTreemap->getGroup(dupNames[j]); + + //update pcounts + itCounts = tree[i].pcount.find(group); + if (itCounts == tree[i].pcount.end()) { //new group, add it + tree[i].pcount[group] = 1; + }else { + tree[i].pcount[group]++; + } + + //update pgroups + itCounts = tree[i].pGroups.find(group); + if (itCounts == tree[i].pGroups.end()) { //new group, add it + tree[i].pGroups[group] = 1; + }else { + tree[i].pGroups[group]++; + } + + //keep highest group + if(tree[i].pGroups[group] > maxPars){ + maxPars = tree[i].pGroups[group]; + } + }//end if + }//end for + + if (maxPars > 1) { //then we have some more dominant groups + //erase all the groups that are less than maxPars because you found a more dominant group. + for(it=tree[i].pGroups.begin();it!=tree[i].pGroups.end();){ + if(it->second < maxPars){ + tree[i].pGroups.erase(it++); + }else { it++; } + } + //set one remaining groups to 1 + for(it=tree[i].pGroups.begin();it!=tree[i].pGroups.end();it++){ + tree[i].pGroups[it->first] = 1; + } + }//end if + + //update groups to reflect all the groups this node represents + vector nodeGroups; + map::iterator itGroups; + for (itGroups = tree[i].pcount.begin(); itGroups != tree[i].pcount.end(); itGroups++) { + nodeGroups.push_back(itGroups->first); + } + tree[i].setGroup(nodeGroups); + + }//end else + }//end for + + } + catch(exception& e) { + m->errorOut(e, "Tree", "addNamesToCounts"); + exit(1); + } +} +/*****************************************************************/ int Tree::getIndex(string searchName) { try { //Treemap knows name, group and index to speed up search @@ -63,13 +149,9 @@ int Tree::getIndex(string searchName) { } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function getIndex. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "getIndex"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function getIndex. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ @@ -79,31 +161,31 @@ void Tree::setIndex(string searchName, int index) { globaldata->gTreemap->setIndex(searchName, index); } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function setIndex. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "setIndex"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function setIndex. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ -void Tree::assembleTree() { +int Tree::assembleTree() { try { + + //if user has given a names file we want to include that info in the pgroups and pcount info. + if(globaldata->names.size() != 0) { addNamesToCounts(); } + //build the pGroups in non leaf nodes to be used in the parsimony calcs. for (int i = numLeaves; i < numNodes; i++) { + if (m->control_pressed) { return 1; } + tree[i].pGroups = (mergeGroups(i)); tree[i].pcount = (mergeGcounts(i)); } + + return 0; } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function assembleTree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "assembleTree"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function assembleTree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ void Tree::getCopy(Tree* copy) { @@ -136,15 +218,12 @@ void Tree::getCopy(Tree* copy) { //copy pcount tree[i].pcount = copy->tree[i].pcount; } + } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function getCopy. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "getCopy"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function getCopy. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ //returns a map with a groupname and the number of times that group was seen in the children @@ -179,11 +258,10 @@ map Tree::mergeGroups(int i) { // this is true if right child had a greater parsimony for a certain group if(maxPars > 1){ //erase all the groups that are only 1 because you found something with 2. - for(it=parsimony.begin();it!=parsimony.end();it++){ + for(it=parsimony.begin();it!=parsimony.end();){ if(it->second == 1){ - parsimony.erase(it->first); -// it--; - } + parsimony.erase(it++); + }else { it++; } } //set one remaining groups to 1 //so with our above example p[white] = 2 would be left and it would become p[white] = 1 @@ -196,13 +274,9 @@ map Tree::mergeGroups(int i) { return parsimony; } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function mergeGroups. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "mergeGroups"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function mergeGroups. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ //returns a map with a groupname and the number of times that group was seen in the children @@ -217,13 +291,17 @@ map Tree::mergeUserGroups(int i, vector g) { int rc = tree[i].getRChild(); //loop through nodes groups removing the ones the user doesn't want - for (it = tree[lc].pGroups.begin(); it != tree[lc].pGroups.end(); it++) { - if (inUsersGroups(it->first, g) != true) { tree[lc].pGroups.erase(it->first); } + for(it=tree[lc].pGroups.begin();it!=tree[lc].pGroups.end();){ + if (inUsersGroups(it->first, g) != true) { + tree[lc].pGroups.erase(it++); + }else { it++; } } - + //loop through nodes groups removing the ones the user doesn't want - for (it = tree[rc].pGroups.begin(); it != tree[rc].pGroups.end(); it++) { - if (inUsersGroups(it->first, g) != true) { tree[rc].pGroups.erase(it->first); } + for(it=tree[rc].pGroups.begin();it!=tree[rc].pGroups.end();){ + if (inUsersGroups(it->first, g) != true) { + tree[rc].pGroups.erase(it++); + }else { it++; } } //set parsimony groups to left child @@ -248,11 +326,12 @@ map Tree::mergeUserGroups(int i, vector g) { // this is true if right child had a greater parsimony for a certain group if(maxPars > 1){ //erase all the groups that are only 1 because you found something with 2. - for(it=parsimony.begin();it!=parsimony.end();it++){ + for(it=parsimony.begin();it!=parsimony.end();){ if(it->second == 1){ - parsimony.erase(it->first); - } + parsimony.erase(it++); + }else { it++; } } + for(it=parsimony.begin();it!=parsimony.end();it++){ parsimony[it->first] = 1; } @@ -261,13 +340,9 @@ map Tree::mergeUserGroups(int i, vector g) { return parsimony; } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function mergeGroups. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "mergeUserGroups"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function mergeGroups. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } @@ -288,13 +363,9 @@ map Tree::mergeGcounts(int position) { return sum; } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function mergeGcounts. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "mergeGcounts"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function mergeGcounts. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /**************************************************************************************************/ @@ -319,7 +390,7 @@ void Tree::randomLabels(vector g) { tree[z].pGroups = (tree[i].pGroups); tree[i].pGroups = (lib_hold); - string zgroup = tree[z].getGroup(); + vector zgroup = tree[z].getGroup(); tree[z].setGroup(tree[i].getGroup()); tree[i].setGroup(zgroup); @@ -334,15 +405,11 @@ void Tree::randomLabels(vector g) { } } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function randomLabels. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "randomLabels"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function randomLabels. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } -/**************************************************************************************************/ +/************************************************************************************************** void Tree::randomLabels(string groupA, string groupB) { try { @@ -368,13 +435,9 @@ void Tree::randomLabels(string groupA, string groupB) { } } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function randomLabels. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "randomLabels"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function randomLabels. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /**************************************************************************************************/ void Tree::randomBlengths() { @@ -388,13 +451,9 @@ void Tree::randomBlengths() { } } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function randomBlengths. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "randomBlengths"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function randomBlengths. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*************************************************************************************************/ void Tree::assembleRandomUnifracTree(vector g) { @@ -403,7 +462,9 @@ void Tree::assembleRandomUnifracTree(vector g) { } /*************************************************************************************************/ void Tree::assembleRandomUnifracTree(string groupA, string groupB) { - randomLabels(groupA, groupB); + + vector temp; temp.push_back(groupA); temp.push_back(groupB); + randomLabels(temp); assembleTree(); } @@ -439,7 +500,7 @@ void Tree::randomTopology() { escape = 1; } } - + tree[i].setChildren(rnd_index1,rnd_index2); tree[i].setParent(-1); tree[rnd_index1].setParent(i); @@ -447,13 +508,9 @@ void Tree::randomTopology() { } } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function randomTopology. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "randomTopology"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function randomTopology. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ void Tree::print(ostream& out) { @@ -463,13 +520,9 @@ void Tree::print(ostream& out) { out << ";" << endl; } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function print. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "print"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function print. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ void Tree::printForBoot(ostream& out) { @@ -479,13 +532,9 @@ void Tree::printForBoot(ostream& out) { out << ";" << endl; } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function printForBoot. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "printForBoot"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function printForBoot. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ @@ -505,13 +554,9 @@ void Tree::createNewickFile(string f) { out.close(); } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function createNewickFile. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "createNewickFile"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function createNewickFile. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ @@ -528,13 +573,9 @@ int Tree::findRoot() { return -1; } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function findRoot. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "findRoot"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function findRoot. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ @@ -560,7 +601,9 @@ void Tree::printBranch(int node, ostream& out, string mode) { } } }else { //you are a leaf - out << tree[node].getGroup(); + string leafGroup = globaldata->gTreemap->getGroup(tree[node].getName()); + + out << leafGroup; if (mode == "branch") { //if there is a branch length then print it if (tree[node].getBranchLength() != -1) { @@ -576,13 +619,9 @@ void Tree::printBranch(int node, ostream& out, string mode) { } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function printBranch. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "printBranch"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function printBranch. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*****************************************************************/ @@ -597,7 +636,7 @@ void Tree::printTree() { } /*****************************************************************/ - +//this code is a mess and should be rethought...-slw void Tree::parseTreeFile() { //only takes names from the first tree and assumes that all trees use the same names. @@ -607,6 +646,7 @@ void Tree::parseTreeFile() { openInputFile(filename, filehandle); int c, comment; comment = 0; + int done = 1; //ifyou are not a nexus file if((c = filehandle.peek()) != '#') { @@ -623,7 +663,8 @@ void Tree::parseTreeFile() { filehandle.get(); } - readTreeString(filehandle); + done = readTreeString(filehandle); + if (done == 0) { break; } } //ifyou are a nexus file }else if((c = filehandle.peek()) == '#') { @@ -638,17 +679,20 @@ void Tree::parseTreeFile() { comment = 0; } filehandle >> holder; - - //ifthere is no translate then you must read tree string otherwise use translate to get names - if(holder == "tree" && comment != 1){ + + //if there is no translate then you must read tree string otherwise use translate to get names + if((holder == "tree") && (comment != 1)){ //pass over the "tree rep.6878900 = " while (((c = filehandle.get()) != '(') && ((c = filehandle.peek()) != EOF)) {;} if(c == EOF) { break; } filehandle.putback(c); //put back first ( of tree. - readTreeString(filehandle); + done = readTreeString(filehandle); + break; } + + if (done == 0) { break; } } //use nexus translation rather than parsing tree to save time @@ -671,33 +715,39 @@ void Tree::parseTreeFile() { filehandle.close(); } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function parseTreeFile. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "parseTreeFile"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function parseTreeFile. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*******************************************************/ /*******************************************************/ -void Tree::readTreeString(ifstream& filehandle) { +int Tree::readTreeString(ifstream& filehandle) { try { int c; - string name; //k + string name; //, k while((c = filehandle.peek()) != ';') { - //ifyou are a name +//k = c; +//cout << " at beginning of while " << k << endl; + if(c == ')') { + //to pass over labels in trees + c=filehandle.get(); + while((c!=',') && (c != -1) && (c!= ':') && (c!=';')){ c=filehandle.get(); } + filehandle.putback(c); + } + if(c == ';') { return 0; } + if(c == -1) { return 0; } + //if you are a name if((c != '(') && (c != ')') && (c != ',') && (c != ':') && (c != '\n') && (c != '\t') && (c != 32)) { //32 is space name = ""; c = filehandle.get(); - // k = c; + //k = c; //cout << k << endl; while ((c != '(') && (c != ')') && (c != ',') && (c != ':') && (c != '\n') && (c != 32) && (c != '\t')) { name += c; c = filehandle.get(); - // k = c; + //k = c; //cout << " in name while " << k << endl; } @@ -711,26 +761,27 @@ void Tree::readTreeString(ifstream& filehandle) { if(c == ':') { //read until you reach the end of the branch length while ((c != '(') && (c != ')') && (c != ',') && (c != ';') && (c != '\n') && (c != '\t') && (c != 32)) { c = filehandle.get(); - // k = c; + //k = c; //cout << " in branch while " << k << endl; } filehandle.putback(c); } + c = filehandle.get(); - if(c == ';') { break; } - // k = c; +//k = c; + //cout << " here after get " << k << endl; + if(c == ';') { return 0; } + if(c == ')') { filehandle.putback(c); } + //k = c; //cout << k << endl; } + return 0; } catch(exception& e) { - cout << "Standard Error: " << e.what() << " has occurred in the Tree class Function parseTreeFile. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; + m->errorOut(e, "Tree", "readTreeString"); exit(1); } - catch(...) { - cout << "An unknown error has occurred in the Tree class function parseTreeFile. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n"; - exit(1); - } } /*******************************************************/