5 * Created by Pat Schloss on 6/17/09.
6 * Copyright 2009 Patrick D. Schloss. All rights reserved.
10 #include "phylotree.h"
12 /**************************************************************************************************/
14 PhyloTree::PhyloTree(){
18 tree.push_back(TaxNode("Root"));
19 tree[0].heirarchyID = "0";
22 errorOut(e, "PhyloTree", "PhyloTree");
26 /**************************************************************************************************/
28 PhyloTree::PhyloTree(string tfile){
32 tree.push_back(TaxNode("Root"));
33 tree[0].heirarchyID = "0";
36 openInputFile(tfile, in);
38 //read in users taxonomy file and add sequences to tree
41 in >> name >> tax; gobble(in);
43 addSeqToTree(name, tax);
47 assignHeirarchyIDs(0);
50 errorOut(e, "PhyloTree", "PhyloTree");
55 /**************************************************************************************************/
57 string PhyloTree::getNextTaxon(string& heirarchy){
59 string currentLevel = "";
61 currentLevel=heirarchy.substr(0,heirarchy.find_first_of(';'));
62 heirarchy=heirarchy.substr(heirarchy.find_first_of(';')+1);
67 errorOut(e, "PhyloTree", "getNextTaxon");
72 /**************************************************************************************************/
74 void PhyloTree::addSeqToTree(string seqName, string seqTaxonomy){
78 map<string, int>::iterator childPointer;
83 tree[0].accessions.push_back(seqName);
84 string taxon;// = getNextTaxon(seqTaxonomy);
86 while(seqTaxonomy != ""){
90 //somehow the parent is getting one too many accnos
91 //use print to reassign the taxa id
92 taxon = getNextTaxon(seqTaxonomy);
94 childPointer = tree[currentNode].children.find(taxon);
96 if(childPointer != tree[currentNode].children.end()){ //if the node already exists, move on
97 currentNode = childPointer->second;
98 tree[currentNode].accessions.push_back(seqName);
99 name2Taxonomy[seqName] = currentNode;
101 else{ //otherwise, create it
102 tree.push_back(TaxNode(taxon));
104 tree[currentNode].children[taxon] = numNodes-1;
105 tree[numNodes-1].parent = currentNode;
107 // int numChildren = tree[currentNode].children.size();
108 // string heirarchyID = tree[currentNode].heirarchyID;
109 // tree[currentNode].accessions.push_back(seqName);
111 currentNode = tree[currentNode].children[taxon];
112 tree[currentNode].accessions.push_back(seqName);
113 name2Taxonomy[seqName] = currentNode;
114 // tree[currentNode].level = level;
115 // tree[currentNode].childNumber = numChildren;
116 // tree[currentNode].heirarchyID = heirarchyID + '.' + toString(tree[currentNode].childNumber);
119 if (seqTaxonomy == "") { uniqueTaxonomies[currentNode] = currentNode; }
123 catch(exception& e) {
124 errorOut(e, "PhyloTree", "addSeqToTree");
128 /**************************************************************************************************/
129 vector<int> PhyloTree::getGenusNodes() {
132 //generate genusIndexes
133 map<int, int>::iterator it2;
134 for (it2=uniqueTaxonomies.begin(); it2!=uniqueTaxonomies.end(); it2++) { genusIndex.push_back(it2->first); }
138 catch(exception& e) {
139 errorOut(e, "PhyloTree", "getGenusNodes");
143 /**************************************************************************************************/
145 void PhyloTree::assignHeirarchyIDs(int index){
147 map<string,int>::iterator it;
150 for(it=tree[index].children.begin();it!=tree[index].children.end();it++){
151 tree[it->second].heirarchyID = tree[index].heirarchyID + '.' + toString(counter);
153 tree[it->second].level = tree[index].level + 1;
154 assignHeirarchyIDs(it->second);
157 catch(exception& e) {
158 errorOut(e, "PhyloTree", "assignHeirarchyIDs");
163 /**************************************************************************************************/
165 void PhyloTree::print(ofstream& out){
167 out << tree[0].level << '\t'<< tree[0].heirarchyID << '\t' << tree[0].name << '\t' << tree[0].children.size() << '\t' << tree[0].accessions.size() << endl;
170 catch(exception& e) {
171 errorOut(e, "PhyloTree", "print");
176 /**************************************************************************************************/
178 void PhyloTree::print(int i, ofstream& out){
180 map<string,int>::iterator it;
181 for(it=tree[i].children.begin();it!=tree[i].children.end();it++){
182 out <<tree[it->second].level << '\t' << tree[it->second].heirarchyID << '\t' << tree[it->second].name << '\t' << tree[it->second].children.size() << '\t' << tree[it->second].accessions.size() << endl;
183 print(it->second, out);
186 catch(exception& e) {
187 errorOut(e, "PhyloTree", "print");
192 /**************************************************************************************************/