]> git.donarmstrong.com Git - mothur.git/blob - indicatorcommand.cpp
added set.current and get.current commands and modified existing commands to update...
[mothur.git] / indicatorcommand.cpp
1 /*
2  *  indicatorcommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 11/12/10.
6  *  Copyright 2010 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "indicatorcommand.h"
11 #include "sharedutilities.h"
12
13 //**********************************************************************************************************************
14 vector<string> IndicatorCommand::getValidParameters(){  
15         try {
16                 string Array[] =  {"tree","shared","relabund","design","label","groups","outputdir","inputdir"};
17                 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
18                 return myArray;
19         }
20         catch(exception& e) {
21                 m->errorOut(e, "IndicatorCommand", "getValidParameters");
22                 exit(1);
23         }
24 }
25 //**********************************************************************************************************************
26 vector<string> IndicatorCommand::getRequiredParameters(){       
27         try {
28                 string Array[] =  {"tree"};
29                 vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
30                 return myArray;
31         }
32         catch(exception& e) {
33                 m->errorOut(e, "IndicatorCommand", "getRequiredParameters");
34                 exit(1);
35         }
36 }
37 //**********************************************************************************************************************
38 IndicatorCommand::IndicatorCommand(){   
39         try {
40                 abort = true; calledHelp = true; 
41                 vector<string> tempOutNames;
42                 outputTypes["tree"] = tempOutNames;
43                 outputTypes["summary"] = tempOutNames;
44         }
45         catch(exception& e) {
46                 m->errorOut(e, "IndicatorCommand", "IndicatorCommand");
47                 exit(1);
48         }
49 }
50
51 //**********************************************************************************************************************
52 vector<string> IndicatorCommand::getRequiredFiles(){    
53         try {
54                 vector<string> myArray;
55                 return myArray;
56         }
57         catch(exception& e) {
58                 m->errorOut(e, "IndicatorCommand", "getRequiredFiles");
59                 exit(1);
60         }
61 }
62 //**********************************************************************************************************************
63 IndicatorCommand::IndicatorCommand(string option)  {
64         try {
65                 globaldata = GlobalData::getInstance();
66                 abort = false; calledHelp = false;   
67                 
68                 //allow user to run help
69                 if(option == "help") { help(); abort = true; calledHelp = true; }
70                 
71                 else {
72                         //valid paramters for this command
73                         string Array[] =  {"tree","shared","design","relabund","groups","label","outputdir","inputdir"};
74                         vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
75                         
76                         OptionParser parser(option);
77                         map<string, string> parameters = parser.getParameters();
78                         
79                         ValidParameters validParameter;
80                         map<string, string>::iterator it;
81                         
82                         //check to make sure all parameters are valid for command
83                         for (it = parameters.begin(); it != parameters.end(); it++) { 
84                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
85                         }
86                         
87                         globaldata->newRead();
88                         
89                         vector<string> tempOutNames;
90                         outputTypes["tree"] = tempOutNames;
91                         outputTypes["summary"] = tempOutNames;
92                         
93                         //if the user changes the input directory command factory will send this info to us in the output parameter 
94                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
95                         if (inputDir == "not found"){   inputDir = "";          }
96                         else {
97                                 string path;
98                                 it = parameters.find("tree");
99                                 //user has given a template file
100                                 if(it != parameters.end()){ 
101                                         path = m->hasPath(it->second);
102                                         //if the user has not given a path then, add inputdir. else leave path alone.
103                                         if (path == "") {       parameters["tree"] = inputDir + it->second;             }
104                                 }
105                                 
106                                 it = parameters.find("shared");
107                                 //user has given a template file
108                                 if(it != parameters.end()){ 
109                                         path = m->hasPath(it->second);
110                                         //if the user has not given a path then, add inputdir. else leave path alone.
111                                         if (path == "") {       parameters["shared"] = inputDir + it->second;           }
112                                 }
113                                 
114                                 it = parameters.find("relabund");
115                                 //user has given a template file
116                                 if(it != parameters.end()){ 
117                                         path = m->hasPath(it->second);
118                                         //if the user has not given a path then, add inputdir. else leave path alone.
119                                         if (path == "") {       parameters["relabund"] = inputDir + it->second;         }
120                                 }
121                                 
122                                 it = parameters.find("design");
123                                 //user has given a template file
124                                 if(it != parameters.end()){ 
125                                         path = m->hasPath(it->second);
126                                         //if the user has not given a path then, add inputdir. else leave path alone.
127                                         if (path == "") {       parameters["design"] = inputDir + it->second;           }
128                                 }
129                         }
130                         
131                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = ""; }
132
133                         //check for required parameters
134                         treefile = validParameter.validFile(parameters, "tree", true);
135                         if (treefile == "not open") { abort = true; }
136                         else if (treefile == "not found") { treefile = ""; m->mothurOut("tree is a required parameter for the indicator command."); m->mothurOutEndLine(); abort = true;  }     
137                         else {  globaldata->setTreeFile(treefile);  globaldata->setFormat("tree");      }
138                         
139                         sharedfile = validParameter.validFile(parameters, "shared", true);
140                         if (sharedfile == "not open") { abort = true; }
141                         else if (sharedfile == "not found") { sharedfile = ""; }
142                         else { inputFileName = sharedfile; }
143                         
144                         relabundfile = validParameter.validFile(parameters, "relabund", true);
145                         if (relabundfile == "not open") { abort = true; }
146                         else if (relabundfile == "not found") { relabundfile = ""; }
147                         else { inputFileName = relabundfile; }
148                         
149                         designfile = validParameter.validFile(parameters, "design", true);
150                         if (designfile == "not open") { abort = true; }
151                         else if (designfile == "not found") { designfile = ""; }
152                         
153                         groups = validParameter.validFile(parameters, "groups", false);                 
154                         if (groups == "not found") { groups = "";  Groups.push_back("all"); }
155                         else { m->splitAtDash(groups, Groups);  }                       
156                         globaldata->Groups = Groups;
157                         
158                         label = validParameter.validFile(parameters, "label", false);                   
159                         if (label == "not found") { label = ""; m->mothurOut("You did not provide a label, I will use the first label in your inputfile."); m->mothurOutEndLine(); label=""; }  
160                         
161                         if ((relabundfile == "") && (sharedfile == "")) { m->mothurOut("You must provide either a shared or relabund file."); m->mothurOutEndLine(); abort = true;  }
162                         
163                         if ((relabundfile != "") && (sharedfile != "")) { m->mothurOut("You may not use both a shared and relabund file."); m->mothurOutEndLine(); abort = true;  }
164                         
165                 }
166         }
167         catch(exception& e) {
168                 m->errorOut(e, "IndicatorCommand", "IndicatorCommand");         
169                 exit(1);
170         }
171 }
172 //**********************************************************************************************************************
173
174 void IndicatorCommand::help(){
175         try {
176                 m->mothurOut("The indicator command reads a shared or relabund file and a tree file, and outputs a .indicator.tre and .indicator.summary file. \n");
177                 m->mothurOut("The new tree contains labels at each internal node.  The label is the node number so you can relate the tree to the summary file.\n");
178                 m->mothurOut("The summary file lists the indicator value for each OTU for each node.\n");
179                 m->mothurOut("The indicator command parameters are tree, groups, shared, relabund, design and label. The tree parameter is required as well as either shared or relabund.\n");
180                 m->mothurOut("The design parameter allows you to provide a design file to relate the tree to the shared or relabund file.\n");          
181                 m->mothurOut("The groups parameter allows you to specify which of the groups in your shared or relabund you would like analyzed, or if you provide a design file the groups in your design file.  The groups may be entered separated by dashes.\n");
182                 m->mothurOut("The label parameter indicates at what distance your tree relates to the shared or relabund.\n");
183                 m->mothurOut("The indicator command should be used in the following format: indicator(tree=test.tre, shared=test.shared, label=0.03)\n");
184                 m->mothurOut("Note: No spaces between parameter labels (i.e. tree), '=' and parameters (i.e.yourTreefile).\n\n"); 
185         }
186         catch(exception& e) {
187                 m->errorOut(e, "IndicatorCommand", "help");     
188                 exit(1);
189         }
190 }
191
192 //**********************************************************************************************************************
193
194 IndicatorCommand::~IndicatorCommand(){}
195
196 //**********************************************************************************************************************
197
198 int IndicatorCommand::execute(){
199         try {
200                 
201                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
202         
203                 //read designfile if given and set up globaldatas groups for read of sharedfiles
204                 if (designfile != "") {
205                         designMap = new GroupMap(designfile);
206                         designMap->readDesignMap();
207                         
208                         //fill Groups - checks for "all" and for any typo groups
209                         SharedUtil* util = new SharedUtil();
210                         util->setGroups(Groups, designMap->namesOfGroups);
211                         delete util;
212                         
213                         //loop through the Groups and fill Globaldata's Groups with the design file info
214                         globaldata->Groups = designMap->getNamesSeqs(Groups);
215                 }
216         
217                 /***************************************************/
218                 // use smart distancing to get right sharedRabund  //
219                 /***************************************************/
220                 if (sharedfile != "") {  
221                         getShared(); 
222                         if (m->control_pressed) { if (designfile != "") { delete designMap; } for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } return 0; }
223                         if (lookup[0] == NULL) { m->mothurOut("[ERROR] reading shared file."); m->mothurOutEndLine(); return 0; }
224                 }else { 
225                         getSharedFloat(); 
226                         if (m->control_pressed) {  if (designfile != "") { delete designMap; } for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } return 0; }
227                         if (lookupFloat[0] == NULL) { m->mothurOut("[ERROR] reading relabund file."); m->mothurOutEndLine(); return 0; }
228                 }
229                 
230                 //reset Globaldatas groups if needed
231                 if (designfile != "") { globaldata->Groups = Groups; }
232                         
233                 /***************************************************/
234                 //    reading tree info                                                    //
235                 /***************************************************/
236                 string groupfile = ""; 
237                 Tree* tree = new Tree(treefile); delete tree;  //extracts names from tree to make faked out groupmap
238          
239                 globaldata->setGroupFile(groupfile); 
240                 treeMap = new TreeMap();
241                 bool mismatch = false;
242                         
243                 for (int i = 0; i < globaldata->Treenames.size(); i++) { 
244                         //sanity check - is this a group that is not in the sharedfile?
245                         if (designfile == "") {
246                                 if (!(m->inUsersGroups(globaldata->Treenames[i], globaldata->gGroupmap->namesOfGroups))) {
247                                         m->mothurOut("[ERROR]: " + globaldata->Treenames[i] + " is not a group in your shared or relabund file."); m->mothurOutEndLine();
248                                         mismatch = true;
249                                 }
250                                 treeMap->addSeq(globaldata->Treenames[i], "Group1"); 
251                         }else{
252                                 vector<string> myGroups; myGroups.push_back(globaldata->Treenames[i]);
253                                 vector<string> myNames = designMap->getNamesSeqs(myGroups);
254                                 
255                                 for(int k = 0; k < myNames.size(); k++) {
256                                         if (!(m->inUsersGroups(myNames[k], globaldata->gGroupmap->namesOfGroups))) {
257                                                 m->mothurOut("[ERROR]: " + myNames[k] + " is not a group in your shared or relabund file."); m->mothurOutEndLine();
258                                                 mismatch = true;
259                                         }
260                                 }
261                                 treeMap->addSeq(globaldata->Treenames[i], "Group1");
262                         }
263                 }
264                 
265                 if ((designfile != "") && (globaldata->Treenames.size() != Groups.size())) { m->mothurOut("[ERROR]: You design file does not match your tree, aborting."); m->mothurOutEndLine(); mismatch = true; }
266                                 
267                 if (mismatch) { //cleanup and exit
268                         if (designfile != "") { delete designMap; }
269                         if (sharedfile != "") {  for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } }
270                         else { for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } }
271                         delete treeMap;
272                         return 0;
273                 }
274                         
275                 globaldata->gTreemap = treeMap;
276          
277                 read = new ReadNewickTree(treefile);
278                 int readOk = read->read(); 
279                 
280                 if (readOk != 0) { m->mothurOut("Read Terminated."); m->mothurOutEndLine(); globaldata->gTree.clear(); delete globaldata->gTreemap; delete read; return 0; }
281                 
282                 vector<Tree*> T = globaldata->gTree;
283                 
284                 delete read;
285                 
286                 if (m->control_pressed) { 
287                         if (designfile != "") { delete designMap; }
288                         if (sharedfile != "") {  for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } }
289                         else { for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } }
290                         for (int i = 0; i < T.size(); i++) {  delete T[i];  } globaldata->gTree.clear(); delete globaldata->gTreemap; return 0; 
291                 }
292                         
293                 T[0]->assembleTree();
294                                 
295                 /***************************************************/
296                 //    create ouptut tree - respecting pickedGroups //
297                 /***************************************************/
298                 Tree* outputTree = new Tree(globaldata->Groups.size()); 
299                 
300                 outputTree->getSubTree(T[0], globaldata->Groups);
301                 outputTree->assembleTree();
302                         
303                 //no longer need original tree, we have output tree to use and label
304                 for (int i = 0; i < T.size(); i++) {  delete T[i];  } globaldata->gTree.clear();
305                 
306                                 
307                 if (m->control_pressed) { 
308                         if (designfile != "") { delete designMap; }
309                         if (sharedfile != "") {  for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } }
310                         else { for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } }
311                         delete outputTree; delete globaldata->gTreemap;  return 0; 
312                 }
313                 
314                 /***************************************************/
315                 //              get indicator species values                       //
316                 /***************************************************/
317                 GetIndicatorSpecies(outputTree);
318                 
319                 if (designfile != "") { delete designMap; }
320                 
321                 if (m->control_pressed) {  
322                         if (sharedfile != "") {  for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } }
323                         else { for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } }
324                         for (int i = 0; i < outputNames.size(); i++) {  remove(outputNames[i].c_str()); }
325                         delete outputTree; delete globaldata->gTreemap;  return 0; 
326                 }
327                 
328                 //set tree file as new current treefile
329                 string current = "";
330                 itTypes = outputTypes.find("tree");
331                 if (itTypes != outputTypes.end()) {
332                         if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setTreeFile(current); }
333                 }
334                 
335                 m->mothurOutEndLine();
336                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
337                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
338                 m->mothurOutEndLine();
339                                 
340                 return 0;
341         }
342         catch(exception& e) {
343                 m->errorOut(e, "IndicatorCommand", "execute");  
344                 exit(1);
345         }
346 }
347 //**********************************************************************************************************************
348 //traverse tree finding indicator species values for each otu at each node
349 //label node with otu number that has highest indicator value
350 //report all otu values to file
351 int IndicatorCommand::GetIndicatorSpecies(Tree*& T){
352         try {
353                 
354                 string thisOutputDir = outputDir;
355                 if (outputDir == "") {  thisOutputDir += m->hasPath(inputFileName);  }
356                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(inputFileName)) + "indicator.summary";
357                 outputNames.push_back(outputFileName); outputTypes["summary"].push_back(outputFileName);
358                 
359                 ofstream out;
360                 m->openOutputFile(outputFileName, out);
361                 out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
362                 
363                 int numBins = 0;
364                 if (sharedfile != "") { numBins = lookup[0]->getNumBins(); }
365                 else { numBins = lookupFloat[0]->getNumBins(); }
366                 
367                 //print headings
368                 out << "TreeNode\t";
369                 for (int i = 0; i < numBins; i++) { out << "OTU-" << (i+1) << '\t'; }
370                 out << endl;
371                 
372                 string treeOutputDir = outputDir;
373                 if (outputDir == "") {  treeOutputDir += m->hasPath(treefile);  }
374                 string outputTreeFileName = treeOutputDir + m->getRootName(m->getSimpleName(treefile)) + "indicator.tre";
375                 
376                 
377                 //create a map from tree node index to names of descendants, save time later to know which sharedRabund you need
378                 map<int, set<string> > nodeToDescendants;
379                 map<int, set<int> > descendantNodes;
380                 for (int i = 0; i < T->getNumNodes(); i++) {
381                         if (m->control_pressed) { return 0; }
382                         
383                         nodeToDescendants[i] = getDescendantList(T, i, nodeToDescendants, descendantNodes);
384                 }
385                 
386                 //you need the distances to leaf to decide grouping below
387                 //this will also set branch lengths if the tree does not include them
388                 map<int, float> distToRoot = getDistToRoot(T);
389                         
390                 //for each node
391                 for (int i = T->getNumLeaves(); i < T->getNumNodes(); i++) {
392                                 
393                         if (m->control_pressed) { out.close(); return 0; }
394                         
395                         /*****************************************************/
396                         //create vectors containing rabund info                          //
397                         /*****************************************************/
398                         
399                         vector<float> indicatorValues; //size of numBins
400                         
401                         if (sharedfile != "") {
402                                 vector< vector<SharedRAbundVector*> > groupings;
403                                 
404                                 //get nodes that will be a valid grouping
405                                 //you are valid if you are not one of my descendants
406                                 //AND your distToRoot is >= mine
407                                 //AND you were not added as part of a larger grouping. Largest nodes are added first.
408                                 
409                                 set<string> groupsAlreadyAdded;
410                                 //create a grouping with my grouping
411                                 vector<SharedRAbundVector*> subset;
412                                 int count = 0;
413                                 int doneCount = nodeToDescendants[i].size();
414                                 for (int k = 0; k < lookup.size(); k++) {
415                                         //is this descendant of i
416                                         if ((nodeToDescendants[i].count(lookup[k]->getGroup()) != 0)) { 
417                                                 subset.push_back(lookup[k]);
418                                                 groupsAlreadyAdded.insert(lookup[k]->getGroup());
419                                                 count++;
420                                         }
421                                         if (count == doneCount) { break; } //quit once you get the rabunds for this grouping
422                                 }
423                                 if (subset.size() != 0) { groupings.push_back(subset); }
424                                 
425                                 
426                                 for (int j = (T->getNumNodes()-1); j >= 0; j--) {
427         
428                                         
429                                         if ((descendantNodes[i].count(j) == 0) && (distToRoot[j] >= distToRoot[i])) { 
430                                                 vector<SharedRAbundVector*> subset;
431                                                 int count = 0;
432                                                 int doneCount = nodeToDescendants[j].size();
433                                                 for (int k = 0; k < lookup.size(); k++) {
434                                                         //is this descendant of j, and we didn't already add this as part of a larger grouping
435                                                         if ((nodeToDescendants[j].count(lookup[k]->getGroup()) != 0) && (groupsAlreadyAdded.count(lookup[k]->getGroup()) == 0)) { 
436                                                                 subset.push_back(lookup[k]);
437                                                                 groupsAlreadyAdded.insert(lookup[k]->getGroup());
438                                                                 count++;
439                                                         }
440                                                         if (count == doneCount) { break; } //quit once you get the rabunds for this grouping
441                                                 }
442                                                 
443                                                 //if subset.size == 0 then the node was added as part of a larger grouping
444                                                 if (subset.size() != 0) { groupings.push_back(subset); }
445                                         }
446                                 }
447                                 
448                                 if (groupsAlreadyAdded.size() != lookup.size()) {  m->mothurOut("[ERROR]: could not make proper groupings."); m->mothurOutEndLine(); }
449                                                                 
450                                 indicatorValues = getValues(groupings);
451                                 
452                         }else {
453                                 vector< vector<SharedRAbundFloatVector*> > groupings;
454                                 
455                                 //get nodes that will be a valid grouping
456                                 //you are valid if you are not one of my descendants
457                                 //AND your distToRoot is >= mine
458                                 //AND you were not added as part of a larger grouping. Largest nodes are added first.
459                                 
460                                 set<string> groupsAlreadyAdded;
461                                 //create a grouping with my grouping
462                                 vector<SharedRAbundFloatVector*> subset;
463                                 int count = 0;
464                                 int doneCount = nodeToDescendants[i].size();
465                                 for (int k = 0; k < lookupFloat.size(); k++) {
466                                         //is this descendant of i
467                                         if ((nodeToDescendants[i].count(lookupFloat[k]->getGroup()) != 0)) { 
468                                                 subset.push_back(lookupFloat[k]);
469                                                 groupsAlreadyAdded.insert(lookupFloat[k]->getGroup());
470                                                 count++;
471                                         }
472                                         if (count == doneCount) { break; } //quit once you get the rabunds for this grouping
473                                 }
474                                 if (subset.size() != 0) { groupings.push_back(subset); }
475                                 
476                                 for (int j = (T->getNumNodes()-1); j >= 0; j--) {
477                                         if ((descendantNodes[i].count(j) == 0) && (distToRoot[j] >= distToRoot[i])) {
478                                                 vector<SharedRAbundFloatVector*> subset;
479                                                 int count = 0;
480                                                 int doneCount = nodeToDescendants[j].size();
481                                                 for (int k = 0; k < lookupFloat.size(); k++) {
482                                                         //is this descendant of j, and we didn't already add this as part of a larger grouping
483                                                         if ((nodeToDescendants[j].count(lookupFloat[k]->getGroup()) != 0) && (groupsAlreadyAdded.count(lookupFloat[k]->getGroup()) == 0)) { 
484                                                                 subset.push_back(lookupFloat[k]);
485                                                                 groupsAlreadyAdded.insert(lookupFloat[k]->getGroup());
486                                                                 count++;
487                                                         }
488                                                         if (count == doneCount) { break; } //quit once you get the rabunds for this grouping
489                                                 }
490                                                 
491                                                 //if subset.size == 0 then the node was added as part of a larger grouping
492                                                 if (subset.size() != 0) { groupings.push_back(subset); }
493                                         }
494                                 }
495                                 
496                                 if (groupsAlreadyAdded.size() != lookupFloat.size()) { m->mothurOut("[ERROR]: could not make proper groupings."); m->mothurOutEndLine(); }
497                                 
498                                 indicatorValues = getValues(groupings);
499                         }
500                         
501                         if (m->control_pressed) { out.close(); return 0; }
502                         
503                         
504                         /******************************************************/
505                         //output indicator values to table form + label tree  //
506                         /*****************************************************/
507                         out << (i+1) << '\t';
508                         for (int j = 0; j < indicatorValues.size(); j++) {
509                                 
510                                 if (m->control_pressed) { out.close(); return 0; }
511                                 
512                                 out << indicatorValues[j] << '\t';
513                         }
514                         out << endl;
515                         
516                         T->tree[i].setLabel((i+1));
517                         
518                 }
519                 out.close();
520         
521                 ofstream outTree;
522                 m->openOutputFile(outputTreeFileName, outTree);
523                 outputNames.push_back(outputTreeFileName); outputTypes["tree"].push_back(outputTreeFileName);
524                 
525                 T->print(outTree, "both");
526                 outTree.close();
527         
528                 return 0;
529         }
530         catch(exception& e) {
531                 m->errorOut(e, "IndicatorCommand", "GetIndicatorSpecies");      
532                 exit(1);
533         }
534 }
535 //**********************************************************************************************************************
536 vector<float> IndicatorCommand::getValues(vector< vector<SharedRAbundFloatVector*> >& groupings){
537         try {
538                 vector<float> values;
539                 
540                 //for each otu
541                 for (int i = 0; i < groupings[0][0]->getNumBins(); i++) {
542                         
543                         if (m->control_pressed) { return values; }
544                         
545                         vector<float> terms; 
546                         float AijDenominator = 0.0;
547                         vector<float> Bij;
548                         //get overall abundance of each grouping
549                         for (int j = 0; j < groupings.size(); j++) {
550                                 
551                                 float totalAbund = 0;
552                                 int numNotZero = 0;
553                                 for (int k = 0; k < groupings[j].size(); k++) { 
554                                         totalAbund += groupings[j][k]->getAbundance(i); 
555                                         if (groupings[j][k]->getAbundance(i) != 0) { numNotZero++; }
556                                 }
557                                 
558                                 float Aij = (totalAbund / (float) groupings[j].size());
559                                 terms.push_back(Aij);
560                                 
561                                 //percentage of sites represented
562                                 Bij.push_back(numNotZero / (float) groupings[j].size());
563                                 
564                                 AijDenominator += Aij;
565                         }
566                         
567                         float maxIndVal = 0.0;
568                         for (int j = 0; j < terms.size(); j++) { 
569                                 float thisAij = (terms[j] / AijDenominator); 
570                                 float thisValue = thisAij * Bij[j] * 100.0;
571                                 
572                                 //save largest
573                                 if (thisValue > maxIndVal) { maxIndVal = thisValue; }
574                         }
575                         
576                         values.push_back(maxIndVal);
577                 }
578                 
579                 return values;
580         }
581         catch(exception& e) {
582                 m->errorOut(e, "IndicatorCommand", "getValues");        
583                 exit(1);
584         }
585 }
586 //**********************************************************************************************************************
587 //same as above, just data type difference
588 vector<float> IndicatorCommand::getValues(vector< vector<SharedRAbundVector*> >& groupings){
589         try {
590                 vector<float> values;
591                 
592         /*for (int j = 0; j < groupings.size(); j++) {          
593                 cout << "grouping " << j << endl;
594                 for (int k = 0; k < groupings[j].size(); k++) { 
595                         cout << groupings[j][k]->getGroup() << endl;
596                 }
597         }*/
598                 //for each otu
599                 for (int i = 0; i < groupings[0][0]->getNumBins(); i++) {
600                         vector<float> terms; 
601                         float AijDenominator = 0.0;
602                         vector<float> Bij;
603                         //get overall abundance of each grouping
604                         for (int j = 0; j < groupings.size(); j++) {
605         
606                                 int totalAbund = 0.0;
607                                 int numNotZero = 0;
608                                 for (int k = 0; k < groupings[j].size(); k++) { 
609                                         totalAbund += groupings[j][k]->getAbundance(i); 
610                                         if (groupings[j][k]->getAbundance(i) != 0.0) { numNotZero++; }
611                                         
612                                 }
613                                         
614                                 float Aij = (totalAbund / (float) groupings[j].size());
615                                 terms.push_back(Aij);
616                                 
617                                 //percentage of sites represented
618                                 Bij.push_back(numNotZero / (float) groupings[j].size());
619                                 
620                                 AijDenominator += Aij;
621                         }
622                         
623                         float maxIndVal = 0.0;
624                         for (int j = 0; j < terms.size(); j++) { 
625                                 float thisAij = (terms[j] / AijDenominator); 
626                                 float thisValue = thisAij * Bij[j] * 100.0;
627                                         
628                                 //save largest
629                                 if (thisValue > maxIndVal) { maxIndVal = thisValue; }
630                         }
631                         
632                         values.push_back(maxIndVal);
633                 }
634                 
635                 return values;
636         }
637         catch(exception& e) {
638                 m->errorOut(e, "IndicatorCommand", "getValues");        
639                 exit(1);
640         }
641 }
642 //**********************************************************************************************************************
643 //you need the distances to root to decide groupings
644 //this will also set branch lengths if the tree does not include them
645 map<int, float> IndicatorCommand::getDistToRoot(Tree*& T){
646         try {
647                 map<int, float> dists;
648                 
649                 bool hasBranchLengths = false;
650                 for (int i = 0; i < T->getNumNodes(); i++) { 
651                         if (T->tree[i].getBranchLength() > 0.0) {  hasBranchLengths = true; break; }
652                 }
653                 
654                 //set branchlengths if needed
655                 if (!hasBranchLengths) { 
656                         for (int i = 0; i < T->getNumNodes(); i++) {
657                                 
658                                 int lc = T->tree[i].getLChild();
659                                 int rc = T->tree[i].getRChild();
660                                 
661                                 if (lc == -1) { // you are a leaf
662                                         //if you are a leaf set you priliminary length to 1.0, this may adjust later
663                                         T->tree[i].setBranchLength(1.0);
664                                         dists[i] = 1.0;
665                                 }else{ // you are an internal node
666                                         //look at your children's length to leaf
667                                         float ldist = dists[lc];
668                                         float rdist = dists[rc];
669                                         
670                                         float greater = ldist;
671                                         if (rdist > greater) { greater = rdist; dists[i] = ldist + 1.0;}
672                                         else { dists[i] = rdist + 1.0; }
673                                         
674                                         
675                                         //branch length = difference + 1
676                                         T->tree[lc].setBranchLength((abs(ldist-greater) + 1.0));
677                                         T->tree[rc].setBranchLength((abs(rdist-greater) + 1.0));
678                                 }
679                         }
680                 }
681                         
682                 dists.clear();
683                 
684                 for (int i = 0; i < T->getNumNodes(); i++) {
685                         
686                         double sum = 0.0;
687                         int index = i;
688                         
689                         while(T->tree[index].getParent() != -1){
690                                 if (T->tree[index].getBranchLength() != -1) {
691                                         sum += abs(T->tree[index].getBranchLength()); 
692                                 }
693                                 index = T->tree[index].getParent();
694                         }
695                         
696                         dists[i] = sum;
697                 }
698                 
699                 return dists;
700         }
701         catch(exception& e) {
702                 m->errorOut(e, "IndicatorCommand", "getLengthToLeaf");  
703                 exit(1);
704         }
705 }
706 //**********************************************************************************************************************
707 set<string> IndicatorCommand::getDescendantList(Tree*& T, int i, map<int, set<string> > descendants, map<int, set<int> >& nodes){
708         try {
709                 set<string> names;
710                 
711                 set<string>::iterator it;
712                 
713                 int lc = T->tree[i].getLChild();
714                 int rc = T->tree[i].getRChild();
715                 
716                 if (lc == -1) { //you are a leaf your only descendant is yourself
717                         set<int> temp; temp.insert(i);
718                         nodes[i] = temp;
719                         
720                         if (designfile == "") {
721                                 names.insert(T->tree[i].getName());
722                         }else {
723                                 vector<string> myGroup; myGroup.push_back(T->tree[i].getName());
724                                 vector<string> myReps = designMap->getNamesSeqs(myGroup);
725                                 for (int k = 0; k < myReps.size(); k++) {
726                                         names.insert(myReps[k]);
727                                 }
728                         }
729                         
730                 }else{ //your descedants are the combination of your childrens descendants
731                         names = descendants[lc];
732                         nodes[i] = nodes[lc];
733                         for (it = descendants[rc].begin(); it != descendants[rc].end(); it++) {
734                                 names.insert(*it);
735                         }
736                         for (set<int>::iterator itNum = nodes[rc].begin(); itNum != nodes[rc].end(); itNum++) {
737                                 nodes[i].insert(*itNum);
738                         }
739                         //you are your own descendant
740                         nodes[i].insert(i);
741                 }
742                 
743                 return names;
744         }
745         catch(exception& e) {
746                 m->errorOut(e, "IndicatorCommand", "getDescendantList");        
747                 exit(1);
748         }
749 }
750 //**********************************************************************************************************************
751 int IndicatorCommand::getShared(){
752         try {
753                 InputData* input = new InputData(sharedfile, "sharedfile");
754                 lookup = input->getSharedRAbundVectors();
755                 string lastLabel = lookup[0]->getLabel();
756                 
757                 if (label == "") { label = lastLabel; delete input; return 0; }
758                 
759                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
760                 set<string> labels; labels.insert(label);
761                 set<string> processedLabels;
762                 set<string> userLabels = labels;
763                 
764                 //as long as you are not at the end of the file or done wih the lines you want
765                 while((lookup[0] != NULL) && (userLabels.size() != 0)) {
766                         if (m->control_pressed) {  delete input; return 0;  }
767                         
768                         if(labels.count(lookup[0]->getLabel()) == 1){
769                                 processedLabels.insert(lookup[0]->getLabel());
770                                 userLabels.erase(lookup[0]->getLabel());
771                                 break;
772                         }
773                         
774                         if ((m->anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
775                                 string saveLabel = lookup[0]->getLabel();
776                                 
777                                 for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
778                                 lookup = input->getSharedRAbundVectors(lastLabel);
779                                 
780                                 processedLabels.insert(lookup[0]->getLabel());
781                                 userLabels.erase(lookup[0]->getLabel());
782                                 
783                                 //restore real lastlabel to save below
784                                 lookup[0]->setLabel(saveLabel);
785                                 break;
786                         }
787                         
788                         lastLabel = lookup[0]->getLabel();                      
789                         
790                         //get next line to process
791                         //prevent memory leak
792                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
793                         lookup = input->getSharedRAbundVectors();
794                 }
795                 
796                 
797                 if (m->control_pressed) { delete input; return 0;  }
798                 
799                 //output error messages about any remaining user labels
800                 set<string>::iterator it;
801                 bool needToRun = false;
802                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
803                         m->mothurOut("Your file does not include the label " + *it); 
804                         if (processedLabels.count(lastLabel) != 1) {
805                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
806                                 needToRun = true;
807                         }else {
808                                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
809                         }
810                 }
811                 
812                 //run last label if you need to
813                 if (needToRun == true)  {
814                         for (int i = 0; i < lookup.size(); i++) {  if (lookup[i] != NULL) {     delete lookup[i];       } } 
815                         lookup = input->getSharedRAbundVectors(lastLabel);
816                 }       
817                 
818                 delete input;
819                 return 0;
820         }
821         catch(exception& e) {
822                 m->errorOut(e, "IndicatorCommand", "getShared");        
823                 exit(1);
824         }
825 }
826 //**********************************************************************************************************************
827 int IndicatorCommand::getSharedFloat(){
828         try {
829                 InputData* input = new InputData(relabundfile, "relabund");
830                 lookupFloat = input->getSharedRAbundFloatVectors();
831                 string lastLabel = lookupFloat[0]->getLabel();
832                 
833                 if (label == "") { label = lastLabel; delete input; return 0; }
834                 
835                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
836                 set<string> labels; labels.insert(label);
837                 set<string> processedLabels;
838                 set<string> userLabels = labels;
839                 
840                 //as long as you are not at the end of the file or done wih the lines you want
841                 while((lookupFloat[0] != NULL) && (userLabels.size() != 0)) {
842                         
843                         if (m->control_pressed) {  delete input; return 0;  }
844                         
845                         if(labels.count(lookupFloat[0]->getLabel()) == 1){
846                                 processedLabels.insert(lookupFloat[0]->getLabel());
847                                 userLabels.erase(lookupFloat[0]->getLabel());
848                                 break;
849                         }
850                         
851                         if ((m->anyLabelsToProcess(lookupFloat[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
852                                 string saveLabel = lookupFloat[0]->getLabel();
853                                 
854                                 for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } 
855                                 lookupFloat = input->getSharedRAbundFloatVectors(lastLabel);
856                                 
857                                 processedLabels.insert(lookupFloat[0]->getLabel());
858                                 userLabels.erase(lookupFloat[0]->getLabel());
859                                 
860                                 //restore real lastlabel to save below
861                                 lookupFloat[0]->setLabel(saveLabel);
862                                 break;
863                         }
864                         
865                         lastLabel = lookupFloat[0]->getLabel();                 
866                         
867                         //get next line to process
868                         //prevent memory leak
869                         for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } 
870                         lookupFloat = input->getSharedRAbundFloatVectors();
871                 }
872                 
873                 
874                 if (m->control_pressed) { delete input; return 0;  }
875                 
876                 //output error messages about any remaining user labels
877                 set<string>::iterator it;
878                 bool needToRun = false;
879                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
880                         m->mothurOut("Your file does not include the label " + *it); 
881                         if (processedLabels.count(lastLabel) != 1) {
882                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
883                                 needToRun = true;
884                         }else {
885                                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
886                         }
887                 }
888                 
889                 //run last label if you need to
890                 if (needToRun == true)  {
891                         for (int i = 0; i < lookupFloat.size(); i++) {  if (lookupFloat[i] != NULL) {   delete lookupFloat[i];  } } 
892                         lookupFloat = input->getSharedRAbundFloatVectors(lastLabel);
893                 }       
894                 
895                 delete input;
896                 return 0;
897         }
898         catch(exception& e) {
899                 m->errorOut(e, "IndicatorCommand", "getShared");        
900         exit(1);
901         }
902 }               
903 /*****************************************************************/
904
905