5 * Created by Sarah Westcott on 4/29/09.
6 * Copyright 2009 Schloss Lab UMASS AMherst. All rights reserved.
10 #include "concensuscommand.h"
12 //**********************************************************************************************************************
14 ConcensusCommand::ConcensusCommand(string option){
16 globaldata = GlobalData::getInstance();
19 //allow user to run help
20 if(option == "help") { help(); abort = true; }
23 if (option != "") { cout << "There are no valid parameters for the concensus command." << endl; abort = true; }
26 if (globaldata->gTree.size() == 0) { cout << "You must execute the read.tree command, before you may use the concensus command." << endl; abort = true; }
27 else { t = globaldata->gTree; }
31 cout << "Standard Error: " << e.what() << " has occurred in the ConcensusCommand class Function ConcensusCommand. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
35 cout << "An unknown error has occurred in the ConcensusCommand class function ConcensusCommand. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
40 //**********************************************************************************************************************
42 void ConcensusCommand::help(){
44 cout << "The concensus command can only be executed after a successful read.tree command." << "\n";
45 cout << "The concensus command has no parameters." << "\n";
46 cout << "The concensus command should be in the following format: concensus()." << "\n";
47 cout << "The concensus command output two files: .concensus.tre and .concensuspairs." << "\n";
48 cout << "The .concensus.tre file contains the concensus tree of the trees in your input file." << "\n";
49 cout << "The branch lengths are the percentage of trees in your input file that had the given pair." << "\n";
50 cout << "The .concensuspairs file contains a list of the internal nodes in your tree. For each node, the pair that was used in the concensus tree " << "\n";
51 cout << "is reported with its percentage, as well as the other pairs that were seen for that node but not used and their percentages." << "\n" << "\n";
54 cout << "Standard Error: " << e.what() << " has occurred in the ConcensusCommand class Function help. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
58 cout << "An unknown error has occurred in the ConcensusCommand class function help. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
63 //**********************************************************************************************************************
65 ConcensusCommand::~ConcensusCommand(){}
67 //**********************************************************************************************************************
69 int ConcensusCommand::execute(){
72 if (abort == true) { return 0; }
74 numNodes = t[0]->getNumNodes();
75 numLeaves = t[0]->getNumLeaves();
78 //get the possible pairings
81 //print out pairings for testing
82 /*cout << "possible pairing " << endl;
83 for (it2 = nodePairs.begin(); it2 != nodePairs.end(); it2++) {
84 for (int i = 0; i < it2->first.size(); i++) {
85 cout << it2->first[i] << " ";
87 cout << '\t' << it2->second << endl;
91 //open file for pairing not included in the tree
92 notIncluded = getRootName(globaldata->inputFileName) + "concensuspairs";
93 openOutputFile(notIncluded, out2);
95 concensusTree = new Tree();
97 it2 = nodePairs.find(treeSet);
99 nodePairsInTree[treeSet] = it2->second;
101 //erase treeset because you are adding it
102 nodePairs.erase(treeSet);
104 //set count to numLeaves;
107 buildConcensusTree(treeSet);
109 concensusTree->assembleTree();
111 //output species in order
112 out2 << "Species in Order: " << endl << endl;
113 for (int i = 0; i < treeSet.size(); i++) { out2 << i+1 << ". " << treeSet[i] << endl; }
116 //output sets included
117 out2 << endl << "Sets included in the concensus tree:" << endl << endl;
118 for (it2 = nodePairsInTree.begin(); it2 != nodePairsInTree.end(); it2++) {
119 //only output pairs not leaves
120 if (it2->first.size() > 1) {
122 //initialize temp to all "."
123 temp.resize(treeSet.size(), ".");
125 //set the spot in temp that represents it2->first[i] to a "*"
126 for (int i = 0; i < it2->first.size(); i++) {
128 int index = findSpot(it2->first[i]);
133 for (int j = 0; j < temp.size(); j++) {
136 out2 << '\t' << it2->second << endl;
140 //output sets not included
141 out2 << endl << "Sets NOT included in the concensus tree:" << endl << endl;
142 for (it2 = nodePairs.begin(); it2 != nodePairs.end(); it2++) {
144 //initialize temp to all "."
145 temp.resize(treeSet.size(), ".");
147 //set the spot in temp that represents it2->first[i] to a "*"
148 for (int i = 0; i < it2->first.size(); i++) {
150 int index = findSpot(it2->first[i]);
155 for (int j = 0; j < temp.size(); j++) {
158 out2 << '\t' << it2->second << endl;
161 outputFile = getRootName(globaldata->inputFileName) + "concensus.tre";
162 openOutputFile(outputFile, out);
164 concensusTree->printForBoot(out);
166 out.close(); out2.close();
168 delete concensusTree;
172 catch(exception& e) {
173 cout << "Standard Error: " << e.what() << " has occurred in the ConcensusCommand class Function execute. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
177 cout << "An unknown error has occurred in the ConcensusCommand class function execute. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
182 //**********************************************************************************************************************
183 int ConcensusCommand::buildConcensusTree(vector<string> nodeSet) {
185 vector<string> leftChildSet;
186 vector<string> rightChildSet;
188 //if you are at a leaf
189 if (nodeSet.size() == 1) {
190 //return the vector index of the leaf you are at
191 return concensusTree->getIndex(nodeSet[0]);
192 //terminate recursion
193 }else if (count == numNodes) { return 0; }
195 leftChildSet = getNextAvailableSet(nodeSet);
196 rightChildSet = getRestSet(nodeSet, leftChildSet);
197 int left = buildConcensusTree(leftChildSet);
198 int right = buildConcensusTree(rightChildSet);
199 concensusTree->tree[count].setChildren(left, right);
200 concensusTree->tree[count].setLabel(nodePairsInTree[nodeSet]);
201 concensusTree->tree[left].setParent(count);
202 concensusTree->tree[right].setParent(count);
208 catch(exception& e) {
209 cout << "Standard Error: " << e.what() << " has occurred in the ConcensusCommand class Function buildConcensusTree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
213 cout << "An unknown error has occurred in the ConcensusCommand class function buildConcensusTree. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
218 //**********************************************************************************************************************
219 void ConcensusCommand::getSets() {
224 //for each tree add the possible pairs you find
225 for (int i = 0; i < t.size(); i++) {
227 //for each non-leaf node get descendant info.
228 for (int j = numLeaves; j < numNodes; j++) {
230 //go through pcounts and pull out descendants
231 for (it = t[i]->tree[j].pcount.begin(); it != t[i]->tree[j].pcount.end(); it++) {
232 temp.push_back(it->first);
236 sort(temp.begin(), temp.end());
238 it2 = nodePairs.find(temp);
239 if (it2 != nodePairs.end()) {
247 //add each leaf to terminate recursion in concensus
248 //you want the leaves in there but with insignifigant sightings value so it is added last
249 //for each leaf node get descendant info.
250 for (int j = 0; j < numLeaves; j++) {
252 //only need the first one since leaves have no descendants but themselves
253 it = t[0]->tree[j].pcount.begin();
254 temp.clear(); temp.push_back(it->first);
257 treeSet.push_back(it->first);
259 //add leaf to list but with sighting value less then all non leaf pairs
263 sort(treeSet.begin(), treeSet.end());
265 catch(exception& e) {
266 cout << "Standard Error: " << e.what() << " has occurred in the ConcensusCommand class Function getSets. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
270 cout << "An unknown error has occurred in the ConcensusCommand class function getSets. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
275 //**********************************************************************************************************************
276 vector<string> ConcensusCommand::getNextAvailableSet(vector<string> bigset) {
278 vector<string> largest; largest.clear();
279 int largestSighting = -1;
281 //go through the sets
282 for (it2 = nodePairs.begin(); it2 != nodePairs.end(); it2++) {
283 //are you a subset of bigset
284 if (isSubset(bigset, it2->first) == true) {
286 //are you the largest. if you are the same size as current largest refer to sighting
287 if (it2->first.size() > largest.size()) { largest = it2->first; largestSighting = it2->second; }
288 else if (it2->first.size() == largest.size()) {
289 if (it2->second > largestSighting) { largest = it2->first; largestSighting = it2->second; }
295 //save for printing out later and for branch lengths
296 nodePairsInTree[largest] = nodePairs[largest];
298 //delete whatever set you return because it is no longer available
299 nodePairs.erase(largest);
304 catch(exception& e) {
305 cout << "Standard Error: " << e.what() << " has occurred in the ConcensusCommand class Function getNextAvailableSet. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
309 cout << "An unknown error has occurred in the ConcensusCommand class function getNextAvailableSet. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
315 //**********************************************************************************************************************
316 vector<string> ConcensusCommand::getRestSet(vector<string> bigset, vector<string> subset) {
320 for (int i = 0; i < bigset.size(); i++) {
321 bool inSubset = false;
322 for (int j = 0; j < subset.size(); j++) {
323 if (bigset[i] == subset[j]) { inSubset = true; break; }
326 //its not in the subset so put it in the rest
327 if (inSubset == false) { rest.push_back(bigset[i]); }
330 //save for printing out later and for branch lengths
331 nodePairsInTree[rest] = nodePairs[rest];
333 //delete whatever set you return because it is no longer available
334 nodePairs.erase(rest);
339 catch(exception& e) {
340 cout << "Standard Error: " << e.what() << " has occurred in the ConcensusCommand class Function getRestSet. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
344 cout << "An unknown error has occurred in the ConcensusCommand class function getRestSet. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
350 //**********************************************************************************************************************
351 bool ConcensusCommand::isSubset(vector<string> bigset, vector<string> subset) {
354 //check if each guy in suset is also in bigset
355 for (int i = 0; i < subset.size(); i++) {
357 for (int j = 0; j < bigset.size(); j++) {
358 if (subset[i] == bigset[j]) { match = true; break; }
361 //you have a guy in subset that had no match in bigset
362 if (match == false) { return false; }
368 catch(exception& e) {
369 cout << "Standard Error: " << e.what() << " has occurred in the ConcensusCommand class Function isSubset. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
373 cout << "An unknown error has occurred in the ConcensusCommand class function isSubset. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
377 //**********************************************************************************************************************
378 int ConcensusCommand::findSpot(string node) {
382 //check if each guy in suset is also in bigset
383 for (int i = 0; i < treeSet.size(); i++) {
384 if (treeSet[i] == node) { spot = i; break; }
390 catch(exception& e) {
391 cout << "Standard Error: " << e.what() << " has occurred in the ConcensusCommand class Function findSpot. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
395 cout << "An unknown error has occurred in the ConcensusCommand class function findSpot. Please contact Pat Schloss at pschloss@microbio.umass.edu." << "\n";
399 //**********************************************************************************************************************