]> git.donarmstrong.com Git - mothur.git/blob - indicatorcommand.cpp
indicator command
[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 //**********************************************************************************************************************
15 vector<string> IndicatorCommand::setParameters(){       
16         try {
17                 CommandParameter piters("iters", "Number", "", "1000", "", "", "",false,false); parameters.push_back(piters);
18                 CommandParameter pdesign("design", "InputTypes", "", "", "TreeDesign", "TreeDesign", "none",false,false); parameters.push_back(pdesign);
19                 CommandParameter pshared("shared", "InputTypes", "", "", "SharedRel", "SharedRel", "none",false,false); parameters.push_back(pshared);  
20                 CommandParameter prelabund("relabund", "InputTypes", "", "", "SharedRel", "SharedRel", "none",false,false); parameters.push_back(prelabund);
21                 CommandParameter pgroups("groups", "String", "", "", "", "", "",false,false); parameters.push_back(pgroups);
22                 CommandParameter plabel("label", "String", "", "", "", "", "",false,false); parameters.push_back(plabel);
23                 CommandParameter ptree("tree", "InputTypes", "", "", "TreeDesign", "TreeDesign", "none",false,false); parameters.push_back(ptree);
24                 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "",false,false); parameters.push_back(pinputdir);
25                 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "",false,false); parameters.push_back(poutputdir);
26                 
27                 vector<string> myArray;
28                 for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
29                 return myArray;
30         }
31         catch(exception& e) {
32                 m->errorOut(e, "IndicatorCommand", "setParameters");
33                 exit(1);
34         }
35 }
36 //**********************************************************************************************************************
37 string IndicatorCommand::getHelpString(){       
38         try {
39                 string helpString = "";
40                 helpString += "The indicator command reads a shared or relabund file and a tree or design file, and outputs a .indicator.tre and .indicator.summary file. \n";
41                 helpString += "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";
42                 helpString += "The summary file lists the indicator value for each OTU for each node.\n";
43                 helpString += "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";
44                 helpString += "The design parameter allows you to provide a design file to relate the tree to the shared or relabund file.\n";          
45                 helpString += "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";
46                 helpString += "The label parameter indicates at what distance your tree relates to the shared or relabund.\n";
47                 helpString += "The iters parameter allows you to set number of randomization for the P value.  The default is 1000.";
48                 helpString += "The indicator command should be used in the following format: indicator(tree=test.tre, shared=test.shared, label=0.03)\n";
49                 helpString += "Note: No spaces between parameter labels (i.e. tree), '=' and parameters (i.e.yourTreefile).\n"; 
50                 return helpString;
51         }
52         catch(exception& e) {
53                 m->errorOut(e, "IndicatorCommand", "getHelpString");
54                 exit(1);
55         }
56 }
57
58 //**********************************************************************************************************************
59 IndicatorCommand::IndicatorCommand(){   
60         try {
61                 abort = true; calledHelp = true; 
62                 setParameters();
63                 vector<string> tempOutNames;
64                 outputTypes["tree"] = tempOutNames;
65                 outputTypes["summary"] = tempOutNames;
66         }
67         catch(exception& e) {
68                 m->errorOut(e, "IndicatorCommand", "IndicatorCommand");
69                 exit(1);
70         }
71 }
72 //**********************************************************************************************************************
73 IndicatorCommand::IndicatorCommand(string option)  {
74         try {
75                 abort = false; calledHelp = false;   
76                 
77                 //allow user to run help
78                 if(option == "help") { help(); abort = true; calledHelp = true; }
79                 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
80                 
81                 else {
82                         vector<string> myArray = setParameters();
83                         
84                         OptionParser parser(option);
85                         map<string, string> parameters = parser.getParameters();
86                         
87                         ValidParameters validParameter;
88                         map<string, string>::iterator it;
89                         
90                         //check to make sure all parameters are valid for command
91                         for (it = parameters.begin(); it != parameters.end(); it++) { 
92                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
93                         }
94                         
95                         m->runParse = true;
96                         m->Groups.clear();
97                         m->namesOfGroups.clear();
98                         m->Treenames.clear();
99                         m->names.clear();
100                         
101                         vector<string> tempOutNames;
102                         outputTypes["tree"] = tempOutNames;
103                         outputTypes["summary"] = tempOutNames;
104                         
105                         //if the user changes the input directory command factory will send this info to us in the output parameter 
106                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
107                         if (inputDir == "not found"){   inputDir = "";          }
108                         else {
109                                 string path;
110                                 it = parameters.find("tree");
111                                 //user has given a template file
112                                 if(it != parameters.end()){ 
113                                         path = m->hasPath(it->second);
114                                         //if the user has not given a path then, add inputdir. else leave path alone.
115                                         if (path == "") {       parameters["tree"] = inputDir + it->second;             }
116                                 }
117                                 
118                                 it = parameters.find("shared");
119                                 //user has given a template file
120                                 if(it != parameters.end()){ 
121                                         path = m->hasPath(it->second);
122                                         //if the user has not given a path then, add inputdir. else leave path alone.
123                                         if (path == "") {       parameters["shared"] = inputDir + it->second;           }
124                                 }
125                                 
126                                 it = parameters.find("relabund");
127                                 //user has given a template file
128                                 if(it != parameters.end()){ 
129                                         path = m->hasPath(it->second);
130                                         //if the user has not given a path then, add inputdir. else leave path alone.
131                                         if (path == "") {       parameters["relabund"] = inputDir + it->second;         }
132                                 }
133                                 
134                                 it = parameters.find("design");
135                                 //user has given a template file
136                                 if(it != parameters.end()){ 
137                                         path = m->hasPath(it->second);
138                                         //if the user has not given a path then, add inputdir. else leave path alone.
139                                         if (path == "") {       parameters["design"] = inputDir + it->second;           }
140                                 }
141                         }
142                         
143                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = ""; }
144
145                         //check for required parameters
146                         treefile = validParameter.validFile(parameters, "tree", true);
147                         if (treefile == "not open") { treefile = ""; abort = true; }
148                         else if (treefile == "not found") { treefile = "";      }               
149                         else { m->setTreeFile(treefile); }      
150                         
151                         sharedfile = validParameter.validFile(parameters, "shared", true);
152                         if (sharedfile == "not open") { abort = true; }
153                         else if (sharedfile == "not found") { sharedfile = ""; }
154                         else { inputFileName = sharedfile; m->setSharedFile(sharedfile); }
155                         
156                         relabundfile = validParameter.validFile(parameters, "relabund", true);
157                         if (relabundfile == "not open") { abort = true; }
158                         else if (relabundfile == "not found") { relabundfile = ""; }
159                         else { inputFileName = relabundfile; m->setRelAbundFile(relabundfile); }
160                         
161                         designfile = validParameter.validFile(parameters, "design", true);
162                         if (designfile == "not open") { designfile = ""; abort = true; }
163                         else if (designfile == "not found") { designfile = ""; }
164                         else { m->setDesignFile(designfile); }
165                         
166                         groups = validParameter.validFile(parameters, "groups", false);                 
167                         if (groups == "not found") { groups = "";  Groups.push_back("all"); }
168                         else { m->splitAtDash(groups, Groups);  }                       
169                         m->Groups = Groups;
170                         
171                         label = validParameter.validFile(parameters, "label", false);                   
172                         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=""; }  
173                         
174                         string temp = validParameter.validFile(parameters, "iters", false);             if (temp == "not found") { temp = "1000"; }
175                         convert(temp, iters); 
176                         
177                         if ((relabundfile == "") && (sharedfile == "")) { 
178                                 //is there are current file available for either of these?
179                                 //give priority to shared, then relabund
180                                 sharedfile = m->getSharedFile(); 
181                                 if (sharedfile != "") {  inputFileName = sharedfile; m->mothurOut("Using " + sharedfile + " as input file for the shared parameter."); m->mothurOutEndLine(); }
182                                 else { 
183                                         relabundfile = m->getRelAbundFile(); 
184                                         if (relabundfile != "") {  inputFileName = relabundfile; m->mothurOut("Using " + relabundfile + " as input file for the relabund parameter."); m->mothurOutEndLine(); }
185                                         else { 
186                                                 m->mothurOut("No valid current files. You must provide a shared or relabund."); m->mothurOutEndLine(); 
187                                                 abort = true;
188                                         }
189                                 }
190                         }
191                         
192                         
193                         if ((designfile == "") && (treefile == "")) { 
194                                 treefile = m->getTreeFile(); 
195                                 if (treefile != "") {  m->mothurOut("Using " + treefile + " as input file for the tree parameter."); m->mothurOutEndLine(); }
196                                 else { 
197                                         designfile = m->getDesignFile(); 
198                                         if (designfile != "") {  m->mothurOut("Using " + designfile + " as input file for the design parameter."); m->mothurOutEndLine(); }
199                                         else { 
200                                                 m->mothurOut("[ERROR]: You must provide either a tree or design file."); m->mothurOutEndLine(); abort = true; 
201                                         }
202                                 }
203                         }
204                         
205                         if ((relabundfile != "") && (sharedfile != "")) { m->mothurOut("[ERROR]: You may not use both a shared and relabund file."); m->mothurOutEndLine(); abort = true;  }
206                         
207                 }
208         }
209         catch(exception& e) {
210                 m->errorOut(e, "IndicatorCommand", "IndicatorCommand");         
211                 exit(1);
212         }
213 }
214 //**********************************************************************************************************************
215
216 int IndicatorCommand::execute(){
217         try {
218                 
219                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
220                 
221                 cout.setf(ios::fixed, ios::floatfield); cout.setf(ios::showpoint);
222         
223                 //read designfile if given and set up globaldatas groups for read of sharedfiles
224                 if (designfile != "") {
225                         designMap = new GroupMap(designfile);
226                         designMap->readDesignMap();
227                         
228                         //fill Groups - checks for "all" and for any typo groups
229                         SharedUtil* util = new SharedUtil();
230                         util->setGroups(Groups, designMap->namesOfGroups);
231                         delete util;
232                         
233                         //loop through the Groups and fill Globaldata's Groups with the design file info
234                         m->Groups = designMap->getNamesSeqs(Groups);
235                 }
236         
237                 /***************************************************/
238                 // use smart distancing to get right sharedRabund  //
239                 /***************************************************/
240                 if (sharedfile != "") {  
241                         getShared(); 
242                         if (m->control_pressed) { if (designfile != "") { delete designMap; } for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } return 0; }
243                         if (lookup[0] == NULL) { m->mothurOut("[ERROR] reading shared file."); m->mothurOutEndLine(); return 0; }
244                 }else { 
245                         getSharedFloat(); 
246                         if (m->control_pressed) {  if (designfile != "") { delete designMap; } for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } return 0; }
247                         if (lookupFloat[0] == NULL) { m->mothurOut("[ERROR] reading relabund file."); m->mothurOutEndLine(); return 0; }
248                 }
249                 
250                 //reset Globaldatas groups if needed
251                 if (designfile != "") { m->Groups = Groups; }
252                         
253                 /***************************************************/
254                 //    reading tree info                                                    //
255                 /***************************************************/
256                 if (treefile != "") {
257                         string groupfile = ""; 
258                         m->setTreeFile(treefile);
259                         Tree* tree = new Tree(treefile); delete tree;  //extracts names from tree to make faked out groupmap
260                         treeMap = new TreeMap();
261                         bool mismatch = false;
262                                 
263                         for (int i = 0; i < m->Treenames.size(); i++) { 
264                                 //sanity check - is this a group that is not in the sharedfile?
265                                 if (designfile == "") {
266                                         if (!(m->inUsersGroups(m->Treenames[i], m->namesOfGroups))) {
267                                                 m->mothurOut("[ERROR]: " + m->Treenames[i] + " is not a group in your shared or relabund file."); m->mothurOutEndLine();
268                                                 mismatch = true;
269                                         }
270                                         treeMap->addSeq(m->Treenames[i], "Group1"); 
271                                 }else{
272                                         vector<string> myGroups; myGroups.push_back(m->Treenames[i]);
273                                         vector<string> myNames = designMap->getNamesSeqs(myGroups);
274                                         
275                                         for(int k = 0; k < myNames.size(); k++) {
276                                                 if (!(m->inUsersGroups(myNames[k], m->namesOfGroups))) {
277                                                         m->mothurOut("[ERROR]: " + myNames[k] + " is not a group in your shared or relabund file."); m->mothurOutEndLine();
278                                                         mismatch = true;
279                                                 }
280                                         }
281                                         treeMap->addSeq(m->Treenames[i], "Group1");
282                                 }
283                         }
284                         
285                         if ((designfile != "") && (m->Treenames.size() != Groups.size())) { cout << Groups.size() << '\t' << m->Treenames.size() << endl; m->mothurOut("[ERROR]: You design file does not match your tree, aborting."); m->mothurOutEndLine(); mismatch = true; }
286                                         
287                         if (mismatch) { //cleanup and exit
288                                 if (designfile != "") { delete designMap; }
289                                 if (sharedfile != "") {  for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } }
290                                 else { for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } }
291                                 delete treeMap;
292                                 return 0;
293                         }
294                  
295                         read = new ReadNewickTree(treefile);
296                         int readOk = read->read(treeMap); 
297                         
298                         if (readOk != 0) { m->mothurOut("Read Terminated."); m->mothurOutEndLine(); delete treeMap; delete read; return 0; }
299                         
300                         vector<Tree*> T = read->getTrees();
301                         
302                         delete read;
303                         
304                         if (m->control_pressed) { 
305                                 if (designfile != "") { delete designMap; }
306                                 if (sharedfile != "") {  for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } }
307                                 else { for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } }
308                                 for (int i = 0; i < T.size(); i++) {  delete T[i];  }  delete treeMap; return 0; 
309                         }
310                                 
311                         T[0]->assembleTree();
312                                         
313                         /***************************************************/
314                         //    create ouptut tree - respecting pickedGroups //
315                         /***************************************************/
316                         Tree* outputTree = new Tree(m->Groups.size(), treeMap); 
317                         
318                         outputTree->getSubTree(T[0], m->Groups);
319                         outputTree->assembleTree();
320                                 
321                         //no longer need original tree, we have output tree to use and label
322                         for (int i = 0; i < T.size(); i++) {  delete T[i];  } 
323                         
324                                         
325                         if (m->control_pressed) { 
326                                 if (designfile != "") { delete designMap; }
327                                 if (sharedfile != "") {  for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } }
328                                 else { for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } }
329                                 delete outputTree; delete treeMap;  return 0; 
330                         }
331                         
332                         /***************************************************/
333                         //              get indicator species values                       //
334                         /***************************************************/
335                         GetIndicatorSpecies(outputTree);
336                         delete outputTree; delete treeMap;
337                         
338                 }else { //run with design file only
339                         //get indicator species
340                         GetIndicatorSpecies();
341                 }
342                 
343                 if (designfile != "") { delete designMap; }
344                 if (sharedfile != "") {  for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } }
345                 else { for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } }
346                 
347                 if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) {        remove(outputNames[i].c_str()); } return 0; }
348                 
349                 //set tree file as new current treefile
350                 if (treefile != "") {
351                         string current = "";
352                         itTypes = outputTypes.find("tree");
353                         if (itTypes != outputTypes.end()) {
354                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setTreeFile(current); }
355                         }
356                 }
357                 m->mothurOutEndLine();
358                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
359                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
360                 m->mothurOutEndLine();
361                                 
362                 return 0;
363         }
364         catch(exception& e) {
365                 m->errorOut(e, "IndicatorCommand", "execute");  
366                 exit(1);
367         }
368 }
369 //**********************************************************************************************************************
370 //divide shared or relabund file by groupings in the design file
371 //report all otu values to file
372 int IndicatorCommand::GetIndicatorSpecies(){
373         try {
374                 string thisOutputDir = outputDir;
375                 if (outputDir == "") {  thisOutputDir += m->hasPath(inputFileName);  }
376                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(inputFileName)) + "indicator.summary";
377                 outputNames.push_back(outputFileName); outputTypes["summary"].push_back(outputFileName);
378                 
379                 ofstream out;
380                 m->openOutputFile(outputFileName, out);
381                 out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
382                 
383                 int numBins = 0;
384                 if (sharedfile != "") { numBins = lookup[0]->getNumBins(); }
385                 else { numBins = lookupFloat[0]->getNumBins(); }
386                 
387                 if (m->control_pressed) { out.close(); return 0; }
388                         
389                 /*****************************************************/
390                 //create vectors containing rabund info                          //
391                 /*****************************************************/
392                         
393                 vector<float> indicatorValues; //size of numBins
394                 vector<float> pValues;
395                 map< vector<int>, vector<int> > randomGroupingsMap; //maps location in groupings to location in groupings, ie, [0][0] -> [1][2]. This is so we don't have to actually move the sharedRabundVectors.
396                         
397                 if (sharedfile != "") {
398                         vector< vector<SharedRAbundVector*> > groupings;
399                         set<string> groupsAlreadyAdded;
400                         vector<SharedRAbundVector*> subset;
401                         
402                         //for each grouping
403                         for (int i = 0; i < designMap->namesOfGroups.size(); i++) {
404                                 
405                                 for (int k = 0; k < lookup.size(); k++) {
406                                         //are you from this grouping?
407                                         if (designMap->getGroup(lookup[k]->getGroup()) == designMap->namesOfGroups[i]) {
408                                                 subset.push_back(lookup[k]);
409                                                 groupsAlreadyAdded.insert(lookup[k]->getGroup());
410                                         }
411                                 }
412                                 if (subset.size() != 0) { groupings.push_back(subset); }
413                                 subset.clear();
414                         }
415                                 
416                         if (groupsAlreadyAdded.size() != lookup.size()) {  m->mothurOut("[ERROR]: could not make proper groupings."); m->mothurOutEndLine(); }
417                                 
418                         indicatorValues = getValues(groupings, randomGroupingsMap);
419                         
420                         pValues.resize(indicatorValues.size(), 0);
421                         for(int i=0;i<iters;i++){
422                                 if (m->control_pressed) { break; }
423                                 randomGroupingsMap = randomizeGroupings(groupings, lookup.size());
424                                 vector<float> randomIndicatorValues = getValues(groupings, randomGroupingsMap);
425                                 
426                                 for (int j = 0; j < indicatorValues.size(); j++) {
427                                         if (randomIndicatorValues[j] >= indicatorValues[j]) { pValues[j]++; }
428                                 }
429                         }
430                         
431                         for (int i = 0; i < pValues.size(); i++) { pValues[i] /= (double)iters; }
432                                 
433                 }else {
434                         vector< vector<SharedRAbundFloatVector*> > groupings;
435                         set<string> groupsAlreadyAdded;
436                         vector<SharedRAbundFloatVector*> subset;
437                         
438                         //for each grouping
439                         for (int i = 0; i < designMap->namesOfGroups.size(); i++) {
440                                 for (int k = 0; k < lookupFloat.size(); k++) {
441                                         //are you from this grouping?
442                                         if (designMap->getGroup(lookupFloat[k]->getGroup()) == designMap->namesOfGroups[i]) {
443                                                 subset.push_back(lookupFloat[k]);
444                                                 groupsAlreadyAdded.insert(lookupFloat[k]->getGroup());
445                                         }
446                                 }
447                                 if (subset.size() != 0) { groupings.push_back(subset); }
448                                 subset.clear();
449                         }
450                         
451                         if (groupsAlreadyAdded.size() != lookupFloat.size()) {  m->mothurOut("[ERROR]: could not make proper groupings."); m->mothurOutEndLine(); }
452                         
453                         indicatorValues = getValues(groupings, randomGroupingsMap);
454                         
455                         pValues.resize(indicatorValues.size(), 0);
456                         for(int i=0;i<iters;i++){
457                                 if (m->control_pressed) { break; }
458                                 randomGroupingsMap = randomizeGroupings(groupings, lookupFloat.size());
459                                 vector<float> randomIndicatorValues = getValues(groupings, randomGroupingsMap);
460                                 
461                                 for (int j = 0; j < indicatorValues.size(); j++) {
462                                         if (randomIndicatorValues[j] >= indicatorValues[j]) { pValues[j]++; }
463                                 }
464                         }
465                         
466                         for (int i = 0; i < pValues.size(); i++) { pValues[i] /= (double)iters; }
467                 }
468                         
469                 if (m->control_pressed) { out.close(); return 0; }
470                         
471                         
472                 /******************************************************/
473                 //output indicator values to table form               //
474                 /*****************************************************/
475                 int indicatorOTU;
476                 double maxValue, pvalue; maxValue=0.0; pvalue=0.0;
477                 out << "OTU\tIndicator_Value\tpValue" << endl;
478                 for (int j = 0; j < indicatorValues.size(); j++) {
479                                 
480                         if (m->control_pressed) { out.close(); return 0; }
481                         
482                         out << (j+1) << '\t' << indicatorValues[j] << '\t'; 
483                         
484                         if (pValues[j] > (1/(float)iters)) { out << pValues[j] << endl; } 
485                         else { out << "<" << (1/(float)iters) << endl; }
486                         
487                         if (maxValue < indicatorValues[j]) { 
488                                 maxValue = indicatorValues[j];
489                                 indicatorOTU = j;
490                         }
491                 }
492                 
493                 m->mothurOutEndLine(); m->mothurOut("Species\tIndicatorValue\tpValue\n");
494                 cout << "OTU" << indicatorOTU+1 << '\t' << maxValue << '\t';
495                 string pValueString = "<" + toString((1/(float)iters)); 
496                 if (pValues[indicatorOTU] > (1/(float)iters)) { pValueString = toString(pValues[indicatorOTU]); cout << pValues[indicatorOTU];} 
497                 else { cout << "<" << (1/(float)iters); }
498                 m->mothurOutJustToLog("OTU" + toString(indicatorOTU+1) + "\t" + toString(maxValue) + "\t" + pValueString); 
499                 m->mothurOutEndLine(); 
500                 
501                 out.close();
502                 
503                 return 0;
504         }
505         catch(exception& e) {
506                 m->errorOut(e, "IndicatorCommand", "GetIndicatorSpecies");      
507                 exit(1);
508         }
509 }
510 //**********************************************************************************************************************
511 //traverse tree finding indicator species values for each otu at each node
512 //label node with otu number that has highest indicator value
513 //report all otu values to file
514 int IndicatorCommand::GetIndicatorSpecies(Tree*& T){
515         try {
516                 
517                 string thisOutputDir = outputDir;
518                 if (outputDir == "") {  thisOutputDir += m->hasPath(inputFileName);  }
519                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(inputFileName)) + "indicator.summary";
520                 outputNames.push_back(outputFileName); outputTypes["summary"].push_back(outputFileName);
521                 
522                 ofstream out;
523                 m->openOutputFile(outputFileName, out);
524                 out.setf(ios::fixed, ios::floatfield); out.setf(ios::showpoint);
525                 
526                 int numBins = 0;
527                 if (sharedfile != "") { numBins = lookup[0]->getNumBins(); }
528                 else { numBins = lookupFloat[0]->getNumBins(); }
529                 
530                 //print headings
531                 out << "TreeNode\t";
532                 for (int i = 0; i < numBins; i++) { out << "OTU" << (i+1) << "_IndValue" << '\t' << "pValue" << '\t'; }
533                 out << endl;
534                 
535                 m->mothurOutEndLine(); m->mothurOut("Node\tSpecies\tIndicatorValue\tpValue\n");
536                 
537                 string treeOutputDir = outputDir;
538                 if (outputDir == "") {  treeOutputDir += m->hasPath(treefile);  }
539                 string outputTreeFileName = treeOutputDir + m->getRootName(m->getSimpleName(treefile)) + "indicator.tre";
540                 
541                 
542                 //create a map from tree node index to names of descendants, save time later to know which sharedRabund you need
543                 map<int, set<string> > nodeToDescendants;
544                 map<int, set<int> > descendantNodes;
545                 for (int i = 0; i < T->getNumNodes(); i++) {
546                         if (m->control_pressed) { return 0; }
547                         
548                         nodeToDescendants[i] = getDescendantList(T, i, nodeToDescendants, descendantNodes);
549                 }
550                 
551                 //you need the distances to leaf to decide grouping below
552                 //this will also set branch lengths if the tree does not include them
553                 map<int, float> distToRoot = getDistToRoot(T);
554                         
555                 //for each node
556                 for (int i = T->getNumLeaves(); i < T->getNumNodes(); i++) {
557                                 
558                         if (m->control_pressed) { out.close(); return 0; }
559                         
560                         /*****************************************************/
561                         //create vectors containing rabund info                          //
562                         /*****************************************************/
563                         
564                         vector<float> indicatorValues; //size of numBins
565                         vector<float> pValues;
566                         map< vector<int>, vector<int> > randomGroupingsMap; //maps location in groupings to location in groupings, ie, [0][0] -> [1][2]. This is so we don't have to actually move the sharedRabundVectors.
567                         
568                         if (sharedfile != "") {
569                                 vector< vector<SharedRAbundVector*> > groupings;
570                                 
571                                 //get nodes that will be a valid grouping
572                                 //you are valid if you are not one of my descendants
573                                 //AND your distToRoot is >= mine
574                                 //AND you were not added as part of a larger grouping. Largest nodes are added first.
575                                 
576                                 set<string> groupsAlreadyAdded;
577                                 //create a grouping with my grouping
578                                 vector<SharedRAbundVector*> subset;
579                                 int count = 0;
580                                 int doneCount = nodeToDescendants[i].size();
581                                 for (int k = 0; k < lookup.size(); k++) {
582                                         //is this descendant of i
583                                         if ((nodeToDescendants[i].count(lookup[k]->getGroup()) != 0)) { 
584                                                 subset.push_back(lookup[k]);
585                                                 groupsAlreadyAdded.insert(lookup[k]->getGroup());
586                                                 count++;
587                                         }
588                                         if (count == doneCount) { break; } //quit once you get the rabunds for this grouping
589                                 }
590                                 if (subset.size() != 0) { groupings.push_back(subset); }
591                                 
592                                 
593                                 for (int j = (T->getNumNodes()-1); j >= 0; j--) {
594         
595                                         
596                                         if ((descendantNodes[i].count(j) == 0) && (distToRoot[j] >= distToRoot[i])) { 
597                                                 vector<SharedRAbundVector*> subset;
598                                                 int count = 0;
599                                                 int doneCount = nodeToDescendants[j].size();
600                                                 for (int k = 0; k < lookup.size(); k++) {
601                                                         //is this descendant of j, and we didn't already add this as part of a larger grouping
602                                                         if ((nodeToDescendants[j].count(lookup[k]->getGroup()) != 0) && (groupsAlreadyAdded.count(lookup[k]->getGroup()) == 0)) { 
603                                                                 subset.push_back(lookup[k]);
604                                                                 groupsAlreadyAdded.insert(lookup[k]->getGroup());
605                                                                 count++;
606                                                         }
607                                                         if (count == doneCount) { break; } //quit once you get the rabunds for this grouping
608                                                 }
609                                                 
610                                                 //if subset.size == 0 then the node was added as part of a larger grouping
611                                                 if (subset.size() != 0) { groupings.push_back(subset); }
612                                         }
613                                 }
614                                 
615                                 if (groupsAlreadyAdded.size() != lookup.size()) {  m->mothurOut("[ERROR]: could not make proper groupings."); m->mothurOutEndLine(); }
616                                                                 
617                                 indicatorValues = getValues(groupings, randomGroupingsMap);
618                                 
619                                 pValues.resize(indicatorValues.size(), 0);
620                                 for(int i=0;i<iters;i++){
621                                         if (m->control_pressed) { break; }
622                                         randomGroupingsMap = randomizeGroupings(groupings, lookup.size());
623                                         vector<float> randomIndicatorValues = getValues(groupings, randomGroupingsMap);
624                                         
625                                         for (int j = 0; j < indicatorValues.size(); j++) {
626                                                 if (randomIndicatorValues[j] >= indicatorValues[j]) { pValues[j]++; }
627                                         }
628                                 }
629                                 
630                                 for (int i = 0; i < pValues.size(); i++) { pValues[i] /= (double)iters; }
631                                 
632                         }else {
633                                 vector< vector<SharedRAbundFloatVector*> > groupings;
634                                 
635                                 //get nodes that will be a valid grouping
636                                 //you are valid if you are not one of my descendants
637                                 //AND your distToRoot is >= mine
638                                 //AND you were not added as part of a larger grouping. Largest nodes are added first.
639                                 
640                                 set<string> groupsAlreadyAdded;
641                                 //create a grouping with my grouping
642                                 vector<SharedRAbundFloatVector*> subset;
643                                 int count = 0;
644                                 int doneCount = nodeToDescendants[i].size();
645                                 for (int k = 0; k < lookupFloat.size(); k++) {
646                                         //is this descendant of i
647                                         if ((nodeToDescendants[i].count(lookupFloat[k]->getGroup()) != 0)) { 
648                                                 subset.push_back(lookupFloat[k]);
649                                                 groupsAlreadyAdded.insert(lookupFloat[k]->getGroup());
650                                                 count++;
651                                         }
652                                         if (count == doneCount) { break; } //quit once you get the rabunds for this grouping
653                                 }
654                                 if (subset.size() != 0) { groupings.push_back(subset); }
655                                 
656                                 for (int j = (T->getNumNodes()-1); j >= 0; j--) {
657                                         if ((descendantNodes[i].count(j) == 0) && (distToRoot[j] >= distToRoot[i])) {
658                                                 vector<SharedRAbundFloatVector*> subset;
659                                                 int count = 0;
660                                                 int doneCount = nodeToDescendants[j].size();
661                                                 for (int k = 0; k < lookupFloat.size(); k++) {
662                                                         //is this descendant of j, and we didn't already add this as part of a larger grouping
663                                                         if ((nodeToDescendants[j].count(lookupFloat[k]->getGroup()) != 0) && (groupsAlreadyAdded.count(lookupFloat[k]->getGroup()) == 0)) { 
664                                                                 subset.push_back(lookupFloat[k]);
665                                                                 groupsAlreadyAdded.insert(lookupFloat[k]->getGroup());
666                                                                 count++;
667                                                         }
668                                                         if (count == doneCount) { break; } //quit once you get the rabunds for this grouping
669                                                 }
670                                                 
671                                                 //if subset.size == 0 then the node was added as part of a larger grouping
672                                                 if (subset.size() != 0) { groupings.push_back(subset); }
673                                         }
674                                 }
675                                 
676                                 if (groupsAlreadyAdded.size() != lookupFloat.size()) { m->mothurOut("[ERROR]: could not make proper groupings."); m->mothurOutEndLine(); }
677                                 
678                                 indicatorValues = getValues(groupings, randomGroupingsMap);
679                                 
680                                 pValues.resize(indicatorValues.size(), 0);
681                                 for(int i=0;i<iters;i++){
682                                         
683                                         if (m->control_pressed) { break; }
684                                         randomGroupingsMap = randomizeGroupings(groupings, lookup.size());
685                                         vector<float> randomIndicatorValues = getValues(groupings, randomGroupingsMap);
686                                         
687                                         for (int j = 0; j < indicatorValues.size(); j++) {
688                                                 if (randomIndicatorValues[j] >= indicatorValues[j]) { pValues[j]++; }
689                                         }
690                                 }
691                                 
692                                 for (int i = 0; i < pValues.size(); i++) { pValues[i] /= (double)iters; }
693                         }
694                         
695                         if (m->control_pressed) { out.close(); return 0; }
696                         
697                         
698                         /******************************************************/
699                         //output indicator values to table form + label tree  //
700                         /*****************************************************/
701                         out << (i+1) << '\t';
702                         int indicatorOTU;
703                         double maxValue, pvalue; maxValue=0.0; pvalue=0.0;
704                         for (int j = 0; j < indicatorValues.size(); j++) {
705                                 
706                                 if (m->control_pressed) { out.close(); return 0; }
707                                 
708                                 if (pValues[j] < (1/(float)iters)) {
709                                         out << indicatorValues[j] << '\t' << '<' << (1/(float)iters) << '\t';
710                                 }else {
711                                         out << indicatorValues[j] << '\t' << pValues[j] << '\t';
712                                 }
713                                 
714                                 if (maxValue < indicatorValues[j]) { 
715                                         maxValue = indicatorValues[j];
716                                         indicatorOTU = j;
717                                 }
718                         }
719                         out << endl;
720                         
721                         T->tree[i].setLabel((i+1));
722                         
723                         cout << i+1 << "\tOTU" << indicatorOTU+1 << '\t' << maxValue << '\t';
724                         string pValueString = "<" + toString((1/(float)iters)); 
725                         if (pValues[indicatorOTU] > (1/(float)iters)) { pValueString = toString(pValues[indicatorOTU]); cout << pValues[indicatorOTU];} 
726                         else { cout << "<" << (1/(float)iters); }
727                         m->mothurOutJustToLog(toString(i) + "\tOTU" + toString(indicatorOTU+1) + "\t" + toString(maxValue) + "\t" + pValueString); 
728                         m->mothurOutEndLine(); 
729                         
730                         
731                 }
732                 out.close();
733         
734                 ofstream outTree;
735                 m->openOutputFile(outputTreeFileName, outTree);
736                 outputNames.push_back(outputTreeFileName); outputTypes["tree"].push_back(outputTreeFileName);
737                 
738                 T->print(outTree, "both");
739                 outTree.close();
740         
741                 return 0;
742         }
743         catch(exception& e) {
744                 m->errorOut(e, "IndicatorCommand", "GetIndicatorSpecies");      
745                 exit(1);
746         }
747 }
748 //**********************************************************************************************************************
749 vector<float> IndicatorCommand::getValues(vector< vector<SharedRAbundFloatVector*> >& groupings, map< vector<int>, vector<int> > groupingsMap){
750         try {
751                 vector<float> values;
752                 map< vector<int>, vector<int> >::iterator it;
753                 
754                 //for each otu
755                 for (int i = 0; i < groupings[0][0]->getNumBins(); i++) {
756                         
757                         if (m->control_pressed) { return values; }
758                         
759                         vector<float> terms; 
760                         float AijDenominator = 0.0;
761                         vector<float> Bij;
762                         
763                         //get overall abundance of each grouping
764                         for (int j = 0; j < groupings.size(); j++) {
765                                 
766                                 float totalAbund = 0;
767                                 int numNotZero = 0;
768                                 for (int k = 0; k < groupings[j].size(); k++) { 
769                                         vector<int> temp; temp.push_back(j); temp.push_back(k);
770                                         it = groupingsMap.find(temp);
771                                         
772                                         if (it == groupingsMap.end()) { //this one didnt get moved
773                                                 totalAbund += groupings[j][k]->getAbundance(i); 
774                                                 if (groupings[j][k]->getAbundance(i) != 0.0) { numNotZero++; }
775                                         }else {
776                                                 totalAbund += groupings[(it->second)[0]][(it->second)[1]]->getAbundance(i); 
777                                                 if (groupings[(it->second)[0]][(it->second)[1]]->getAbundance(i) != 0.0) { numNotZero++; }
778                                         }
779                                         
780                                 }
781                                 
782                                 //mean abundance
783                                 float Aij = (totalAbund / (float) groupings[j].size());
784                                 terms.push_back(Aij);
785                                 
786                                 //percentage of sites represented
787                                 Bij.push_back(numNotZero / (float) groupings[j].size());
788                                 
789                                 AijDenominator += Aij;
790                         }
791                         
792                         float maxIndVal = 0.0;
793                         for (int j = 0; j < terms.size(); j++) { 
794                                 float thisAij = (terms[j] / AijDenominator); //relative abundance
795                                 float thisValue = thisAij * Bij[j] * 100.0;
796                                 
797                                 //save largest
798                                 if (thisValue > maxIndVal) { maxIndVal = thisValue; }
799                         }
800                         
801                         values.push_back(maxIndVal);
802                 }
803                 
804                 return values;
805         }
806         catch(exception& e) {
807                 m->errorOut(e, "IndicatorCommand", "getValues");        
808                 exit(1);
809         }
810 }
811 //**********************************************************************************************************************
812 //same as above, just data type difference
813 vector<float> IndicatorCommand::getValues(vector< vector<SharedRAbundVector*> >& groupings, map< vector<int>, vector<int> > groupingsMap){
814         try {
815                 vector<float> values;
816                 
817         /*for (int j = 0; j < groupings.size(); j++) {          
818                 cout << "grouping " << j << endl;
819                 for (int k = 0; k < groupings[j].size(); k++) { 
820                         cout << groupings[j][k]->getGroup() << endl;
821                 }
822         }*/
823                 map< vector<int>, vector<int> >::iterator it;
824                 
825                 //for each otu
826                 for (int i = 0; i < groupings[0][0]->getNumBins(); i++) {
827                         vector<float> terms; 
828                         float AijDenominator = 0.0;
829                         vector<float> Bij;
830                         //get overall abundance of each grouping
831                         for (int j = 0; j < groupings.size(); j++) {
832         
833                                 int totalAbund = 0.0;
834                                 int numNotZero = 0;
835                                 for (int k = 0; k < groupings[j].size(); k++) { 
836                                         vector<int> temp; temp.push_back(j); temp.push_back(k);
837                                         it = groupingsMap.find(temp);
838                                         
839                                         if (it == groupingsMap.end()) { //this one didnt get moved
840                                                 totalAbund += groupings[j][k]->getAbundance(i); 
841                                                 if (groupings[j][k]->getAbundance(i) != 0.0) { numNotZero++; }
842                                         }else {
843                                                 totalAbund += groupings[(it->second)[0]][(it->second)[1]]->getAbundance(i); 
844                                                 if (groupings[(it->second)[0]][(it->second)[1]]->getAbundance(i) != 0.0) { numNotZero++; }
845                                         }
846                                         
847                                 }
848                                 
849                                 //mean abundance        
850                                 float Aij = (totalAbund / (float) groupings[j].size());
851                                 terms.push_back(Aij);
852                                 
853                                 //percentage of sites represented
854                                 Bij.push_back(numNotZero / (float) groupings[j].size());
855                                 
856                                 AijDenominator += Aij;
857                         }
858                         
859                         float maxIndVal = 0.0;
860                         for (int j = 0; j < terms.size(); j++) { 
861                                 float thisAij = (terms[j] / AijDenominator); //relative abundance
862                                 float thisValue = thisAij * Bij[j] * 100.0;
863                                         
864                                 //save largest
865                                 if (thisValue > maxIndVal) { maxIndVal = thisValue; }
866                         }
867                         
868                         values.push_back(maxIndVal);
869                 }
870                 
871                 return values;
872         }
873         catch(exception& e) {
874                 m->errorOut(e, "IndicatorCommand", "getValues");        
875                 exit(1);
876         }
877 }
878 //**********************************************************************************************************************
879 //you need the distances to root to decide groupings
880 //this will also set branch lengths if the tree does not include them
881 map<int, float> IndicatorCommand::getDistToRoot(Tree*& T){
882         try {
883                 map<int, float> dists;
884                 
885                 bool hasBranchLengths = false;
886                 for (int i = 0; i < T->getNumNodes(); i++) { 
887                         if (T->tree[i].getBranchLength() > 0.0) {  hasBranchLengths = true; break; }
888                 }
889                 
890                 //set branchlengths if needed
891                 if (!hasBranchLengths) { 
892                         for (int i = 0; i < T->getNumNodes(); i++) {
893                                 
894                                 int lc = T->tree[i].getLChild();
895                                 int rc = T->tree[i].getRChild();
896                                 
897                                 if (lc == -1) { // you are a leaf
898                                         //if you are a leaf set you priliminary length to 1.0, this may adjust later
899                                         T->tree[i].setBranchLength(1.0);
900                                         dists[i] = 1.0;
901                                 }else{ // you are an internal node
902                                         //look at your children's length to leaf
903                                         float ldist = dists[lc];
904                                         float rdist = dists[rc];
905                                         
906                                         float greater = ldist;
907                                         if (rdist > greater) { greater = rdist; dists[i] = ldist + 1.0;}
908                                         else { dists[i] = rdist + 1.0; }
909                                         
910                                         
911                                         //branch length = difference + 1
912                                         T->tree[lc].setBranchLength((abs(ldist-greater) + 1.0));
913                                         T->tree[rc].setBranchLength((abs(rdist-greater) + 1.0));
914                                 }
915                         }
916                 }
917                         
918                 dists.clear();
919                 
920                 for (int i = 0; i < T->getNumNodes(); i++) {
921                         
922                         double sum = 0.0;
923                         int index = i;
924                         
925                         while(T->tree[index].getParent() != -1){
926                                 if (T->tree[index].getBranchLength() != -1) {
927                                         sum += abs(T->tree[index].getBranchLength()); 
928                                 }
929                                 index = T->tree[index].getParent();
930                         }
931                         
932                         dists[i] = sum;
933                 }
934                 
935                 return dists;
936         }
937         catch(exception& e) {
938                 m->errorOut(e, "IndicatorCommand", "getLengthToLeaf");  
939                 exit(1);
940         }
941 }
942 //**********************************************************************************************************************
943 set<string> IndicatorCommand::getDescendantList(Tree*& T, int i, map<int, set<string> > descendants, map<int, set<int> >& nodes){
944         try {
945                 set<string> names;
946                 
947                 set<string>::iterator it;
948                 
949                 int lc = T->tree[i].getLChild();
950                 int rc = T->tree[i].getRChild();
951                 
952                 if (lc == -1) { //you are a leaf your only descendant is yourself
953                         set<int> temp; temp.insert(i);
954                         nodes[i] = temp;
955                         
956                         if (designfile == "") {
957                                 names.insert(T->tree[i].getName());
958                         }else {
959                                 vector<string> myGroup; myGroup.push_back(T->tree[i].getName());
960                                 vector<string> myReps = designMap->getNamesSeqs(myGroup);
961                                 for (int k = 0; k < myReps.size(); k++) {
962                                         names.insert(myReps[k]);
963                                 }
964                         }
965                         
966                 }else{ //your descedants are the combination of your childrens descendants
967                         names = descendants[lc];
968                         nodes[i] = nodes[lc];
969                         for (it = descendants[rc].begin(); it != descendants[rc].end(); it++) {
970                                 names.insert(*it);
971                         }
972                         for (set<int>::iterator itNum = nodes[rc].begin(); itNum != nodes[rc].end(); itNum++) {
973                                 nodes[i].insert(*itNum);
974                         }
975                         //you are your own descendant
976                         nodes[i].insert(i);
977                 }
978                 
979                 return names;
980         }
981         catch(exception& e) {
982                 m->errorOut(e, "IndicatorCommand", "getDescendantList");        
983                 exit(1);
984         }
985 }
986 //**********************************************************************************************************************
987 int IndicatorCommand::getShared(){
988         try {
989                 InputData* input = new InputData(sharedfile, "sharedfile");
990                 lookup = input->getSharedRAbundVectors();
991                 string lastLabel = lookup[0]->getLabel();
992                 
993                 if (label == "") { label = lastLabel; delete input; return 0; }
994                 
995                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
996                 set<string> labels; labels.insert(label);
997                 set<string> processedLabels;
998                 set<string> userLabels = labels;
999                 
1000                 //as long as you are not at the end of the file or done wih the lines you want
1001                 while((lookup[0] != NULL) && (userLabels.size() != 0)) {
1002                         if (m->control_pressed) {  delete input; return 0;  }
1003                         
1004                         if(labels.count(lookup[0]->getLabel()) == 1){
1005                                 processedLabels.insert(lookup[0]->getLabel());
1006                                 userLabels.erase(lookup[0]->getLabel());
1007                                 break;
1008                         }
1009                         
1010                         if ((m->anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
1011                                 string saveLabel = lookup[0]->getLabel();
1012                                 
1013                                 for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
1014                                 lookup = input->getSharedRAbundVectors(lastLabel);
1015                                 
1016                                 processedLabels.insert(lookup[0]->getLabel());
1017                                 userLabels.erase(lookup[0]->getLabel());
1018                                 
1019                                 //restore real lastlabel to save below
1020                                 lookup[0]->setLabel(saveLabel);
1021                                 break;
1022                         }
1023                         
1024                         lastLabel = lookup[0]->getLabel();                      
1025                         
1026                         //get next line to process
1027                         //prevent memory leak
1028                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
1029                         lookup = input->getSharedRAbundVectors();
1030                 }
1031                 
1032                 
1033                 if (m->control_pressed) { delete input; return 0;  }
1034                 
1035                 //output error messages about any remaining user labels
1036                 set<string>::iterator it;
1037                 bool needToRun = false;
1038                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
1039                         m->mothurOut("Your file does not include the label " + *it); 
1040                         if (processedLabels.count(lastLabel) != 1) {
1041                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
1042                                 needToRun = true;
1043                         }else {
1044                                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
1045                         }
1046                 }
1047                 
1048                 //run last label if you need to
1049                 if (needToRun == true)  {
1050                         for (int i = 0; i < lookup.size(); i++) {  if (lookup[i] != NULL) {     delete lookup[i];       } } 
1051                         lookup = input->getSharedRAbundVectors(lastLabel);
1052                 }       
1053                 
1054                 delete input;
1055                 return 0;
1056         }
1057         catch(exception& e) {
1058                 m->errorOut(e, "IndicatorCommand", "getShared");        
1059                 exit(1);
1060         }
1061 }
1062 //**********************************************************************************************************************
1063 int IndicatorCommand::getSharedFloat(){
1064         try {
1065                 InputData* input = new InputData(relabundfile, "relabund");
1066                 lookupFloat = input->getSharedRAbundFloatVectors();
1067                 string lastLabel = lookupFloat[0]->getLabel();
1068                 
1069                 if (label == "") { label = lastLabel; delete input; return 0; }
1070                 
1071                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
1072                 set<string> labels; labels.insert(label);
1073                 set<string> processedLabels;
1074                 set<string> userLabels = labels;
1075                 
1076                 //as long as you are not at the end of the file or done wih the lines you want
1077                 while((lookupFloat[0] != NULL) && (userLabels.size() != 0)) {
1078                         
1079                         if (m->control_pressed) {  delete input; return 0;  }
1080                         
1081                         if(labels.count(lookupFloat[0]->getLabel()) == 1){
1082                                 processedLabels.insert(lookupFloat[0]->getLabel());
1083                                 userLabels.erase(lookupFloat[0]->getLabel());
1084                                 break;
1085                         }
1086                         
1087                         if ((m->anyLabelsToProcess(lookupFloat[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
1088                                 string saveLabel = lookupFloat[0]->getLabel();
1089                                 
1090                                 for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } 
1091                                 lookupFloat = input->getSharedRAbundFloatVectors(lastLabel);
1092                                 
1093                                 processedLabels.insert(lookupFloat[0]->getLabel());
1094                                 userLabels.erase(lookupFloat[0]->getLabel());
1095                                 
1096                                 //restore real lastlabel to save below
1097                                 lookupFloat[0]->setLabel(saveLabel);
1098                                 break;
1099                         }
1100                         
1101                         lastLabel = lookupFloat[0]->getLabel();                 
1102                         
1103                         //get next line to process
1104                         //prevent memory leak
1105                         for (int i = 0; i < lookupFloat.size(); i++) {  delete lookupFloat[i];  } 
1106                         lookupFloat = input->getSharedRAbundFloatVectors();
1107                 }
1108                 
1109                 
1110                 if (m->control_pressed) { delete input; return 0;  }
1111                 
1112                 //output error messages about any remaining user labels
1113                 set<string>::iterator it;
1114                 bool needToRun = false;
1115                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
1116                         m->mothurOut("Your file does not include the label " + *it); 
1117                         if (processedLabels.count(lastLabel) != 1) {
1118                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
1119                                 needToRun = true;
1120                         }else {
1121                                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
1122                         }
1123                 }
1124                 
1125                 //run last label if you need to
1126                 if (needToRun == true)  {
1127                         for (int i = 0; i < lookupFloat.size(); i++) {  if (lookupFloat[i] != NULL) {   delete lookupFloat[i];  } } 
1128                         lookupFloat = input->getSharedRAbundFloatVectors(lastLabel);
1129                 }       
1130                 
1131                 delete input;
1132                 return 0;
1133         }
1134         catch(exception& e) {
1135                 m->errorOut(e, "IndicatorCommand", "getShared");        
1136         exit(1);
1137         }
1138 }       
1139 //**********************************************************************************************************************
1140 //swap groups between groupings, in essence randomizing the second column of the design file
1141 map< vector<int>, vector<int> > IndicatorCommand::randomizeGroupings(vector< vector<SharedRAbundVector*> >& groupings, int numLookupGroups){
1142         try {
1143                 
1144                 map< vector<int>, vector<int> > randomGroupings; 
1145                 
1146                 for (int i = 0; i < numLookupGroups; i++) {
1147                         if (m->control_pressed) {break;}
1148                         
1149                         //get random groups to swap to switch with
1150                         //generate random int between 0 and groupings.size()-1
1151                         int z = m->getRandomIndex(groupings.size()-1);
1152                         int x = m->getRandomIndex(groupings.size()-1);
1153                         int a = m->getRandomIndex(groupings[z].size()-1);
1154                         int b = m->getRandomIndex(groupings[x].size()-1);
1155                         //cout << i << '\t' << z << '\t' << x << '\t' << a << '\t' << b << endl;        
1156                         //if ((z < 0) || (z > 1) || x<0 || x>1 || a <0 || a>groupings[z].size()-1 || b<0 || b>groupings[x].size()-1) { cout << "probelm" << i << '\t' << z << '\t' << x << '\t' << a << '\t' << b << endl;      }
1157                         
1158                         vector<int> from;
1159                         vector<int> to;
1160                         
1161                         from.push_back(z); from.push_back(a);
1162                         to.push_back(x); to.push_back(b);
1163                         
1164                         randomGroupings[from] = to;
1165                 }
1166                 //cout << "done" << endl;       
1167                 return randomGroupings;
1168         }
1169         catch(exception& e) {
1170                 m->errorOut(e, "IndicatorCommand", "randomizeGroupings");       
1171                 exit(1);
1172         }
1173 }       
1174 //**********************************************************************************************************************
1175 //swap groups between groupings, in essence randomizing the second column of the design file
1176 map< vector<int>, vector<int> > IndicatorCommand::randomizeGroupings(vector< vector<SharedRAbundFloatVector*> >& groupings, int numLookupGroups){
1177         try {
1178                 
1179                 map< vector<int>, vector<int> > randomGroupings; 
1180                 
1181                 for (int i = 0; i < numLookupGroups; i++) {
1182                         
1183                         //get random groups to swap to switch with
1184                         //generate random int between 0 and groupings.size()-1
1185                         int z = m->getRandomIndex(groupings.size()-1);
1186                         int x = m->getRandomIndex(groupings.size()-1);
1187                         int a = m->getRandomIndex(groupings[z].size()-1);
1188                         int b = m->getRandomIndex(groupings[x].size()-1);
1189                         //cout << i << '\t' << z << '\t' << x << '\t' << a << '\t' << b << endl;                
1190                         
1191                         vector<int> from;
1192                         vector<int> to;
1193                         
1194                         from.push_back(z); from.push_back(a);
1195                         to.push_back(x); to.push_back(b);
1196                         
1197                         randomGroupings[from] = to;
1198                 }
1199                 
1200                 return randomGroupings;
1201         }
1202         catch(exception& e) {
1203                 m->errorOut(e, "IndicatorCommand", "randomizeGroupings");       
1204                 exit(1);
1205         }
1206 }                       
1207                                                                 
1208 /*****************************************************************/
1209
1210