X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=tree.cpp;h=8e459810589cbc23e9f443884406028382e4e212;hb=28d6f2bddc5c0718ae7f63648be3130a35fb0f02;hp=ce3de379d05d5eca8c991d2e93e64060377a2304;hpb=510b1cfc25cd79391d6973ca20c5ec25fb1bb3b2;p=mothur.git diff --git a/tree.cpp b/tree.cpp index ce3de37..8e45981 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,12 +39,13 @@ 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) { - errorOut(e, "Tree", "Tree"); + m->errorOut(e, "Tree", "Tree"); exit(1); } } @@ -50,6 +53,93 @@ Tree::Tree() { /*****************************************************************/ 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 @@ -59,7 +149,7 @@ int Tree::getIndex(string searchName) { } catch(exception& e) { - errorOut(e, "Tree", "getIndex"); + m->errorOut(e, "Tree", "getIndex"); exit(1); } } @@ -71,21 +161,29 @@ void Tree::setIndex(string searchName, int index) { globaldata->gTreemap->setIndex(searchName, index); } catch(exception& e) { - errorOut(e, "Tree", "setIndex"); + m->errorOut(e, "Tree", "setIndex"); 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) { - errorOut(e, "Tree", "assembleTree"); + m->errorOut(e, "Tree", "assembleTree"); exit(1); } } @@ -120,9 +218,10 @@ void Tree::getCopy(Tree* copy) { //copy pcount tree[i].pcount = copy->tree[i].pcount; } + } catch(exception& e) { - errorOut(e, "Tree", "getCopy"); + m->errorOut(e, "Tree", "getCopy"); exit(1); } } @@ -159,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 @@ -176,7 +274,7 @@ map Tree::mergeGroups(int i) { return parsimony; } catch(exception& e) { - errorOut(e, "Tree", "mergeGroups"); + m->errorOut(e, "Tree", "mergeGroups"); exit(1); } } @@ -193,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 @@ -224,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; } @@ -237,7 +340,7 @@ map Tree::mergeUserGroups(int i, vector g) { return parsimony; } catch(exception& e) { - errorOut(e, "Tree", "mergeUserGroups"); + m->errorOut(e, "Tree", "mergeUserGroups"); exit(1); } } @@ -260,7 +363,7 @@ map Tree::mergeGcounts(int position) { return sum; } catch(exception& e) { - errorOut(e, "Tree", "mergeGcounts"); + m->errorOut(e, "Tree", "mergeGcounts"); exit(1); } } @@ -287,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); @@ -302,11 +405,11 @@ void Tree::randomLabels(vector g) { } } catch(exception& e) { - errorOut(e, "Tree", "randomLabels"); + m->errorOut(e, "Tree", "randomLabels"); exit(1); } } -/**************************************************************************************************/ +/************************************************************************************************** void Tree::randomLabels(string groupA, string groupB) { try { @@ -332,7 +435,7 @@ void Tree::randomLabels(string groupA, string groupB) { } } catch(exception& e) { - errorOut(e, "Tree", "randomLabels"); + m->errorOut(e, "Tree", "randomLabels"); exit(1); } } @@ -348,7 +451,7 @@ void Tree::randomBlengths() { } } catch(exception& e) { - errorOut(e, "Tree", "randomBlengths"); + m->errorOut(e, "Tree", "randomBlengths"); exit(1); } } @@ -359,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(); } @@ -395,7 +500,7 @@ void Tree::randomTopology() { escape = 1; } } - + tree[i].setChildren(rnd_index1,rnd_index2); tree[i].setParent(-1); tree[rnd_index1].setParent(i); @@ -403,7 +508,7 @@ void Tree::randomTopology() { } } catch(exception& e) { - errorOut(e, "Tree", "randomTopology"); + m->errorOut(e, "Tree", "randomTopology"); exit(1); } } @@ -415,7 +520,7 @@ void Tree::print(ostream& out) { out << ";" << endl; } catch(exception& e) { - errorOut(e, "Tree", "print"); + m->errorOut(e, "Tree", "print"); exit(1); } } @@ -427,7 +532,7 @@ void Tree::printForBoot(ostream& out) { out << ";" << endl; } catch(exception& e) { - errorOut(e, "Tree", "printForBoot"); + m->errorOut(e, "Tree", "printForBoot"); exit(1); } } @@ -449,7 +554,7 @@ void Tree::createNewickFile(string f) { out.close(); } catch(exception& e) { - errorOut(e, "Tree", "createNewickFile"); + m->errorOut(e, "Tree", "createNewickFile"); exit(1); } } @@ -468,7 +573,7 @@ int Tree::findRoot() { return -1; } catch(exception& e) { - errorOut(e, "Tree", "findRoot"); + m->errorOut(e, "Tree", "findRoot"); exit(1); } } @@ -496,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) { @@ -512,7 +619,7 @@ void Tree::printBranch(int node, ostream& out, string mode) { } catch(exception& e) { - errorOut(e, "Tree", "printBranch"); + m->errorOut(e, "Tree", "printBranch"); exit(1); } } @@ -529,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. @@ -539,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()) != '#') { @@ -555,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()) == '#') { @@ -570,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 @@ -601,19 +713,23 @@ void Tree::parseTreeFile() { } } filehandle.close(); + + //for (int i = 0; i < globaldata->Treenames.size(); i++) { +//cout << globaldata->Treenames[i] << endl; } +//cout << globaldata->Treenames.size() << endl; } catch(exception& e) { - errorOut(e, "Tree", "parseTreeFile"); + m->errorOut(e, "Tree", "parseTreeFile"); 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()) != ';') { //k = c; @@ -624,7 +740,8 @@ void Tree::readTreeString(ifstream& filehandle) { while((c!=',') && (c != -1) && (c!= ':') && (c!=';')){ c=filehandle.get(); } filehandle.putback(c); } - if(c == ';') { break; } + 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 = ""; @@ -648,22 +765,25 @@ 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; + //cout << " here after get " << k << endl; + if(c == ';') { return 0; } if(c == ')') { filehandle.putback(c); } - // k = c; + //k = c; //cout << k << endl; } + return 0; } catch(exception& e) { - errorOut(e, "Tree", "readTreeString"); + m->errorOut(e, "Tree", "readTreeString"); exit(1); } }