]> git.donarmstrong.com Git - mothur.git/blob - getsharedotucommand.cpp
changing command name classify.shared to classifyrf.shared
[mothur.git] / getsharedotucommand.cpp
1 /*
2  *  getsharedotucommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 9/22/09.
6  *  Copyright 2009 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "getsharedotucommand.h"
11 #include "sharedutilities.h"
12
13 //**********************************************************************************************************************
14 vector<string> GetSharedOTUCommand::setParameters(){    
15         try {
16                 CommandParameter pfasta("fasta", "InputTypes", "", "", "sharedFasta", "none", "none","fasta",false,false); parameters.push_back(pfasta);
17                 CommandParameter pgroup("group", "InputTypes", "", "", "none", "none", "groupList","",false,false,true); parameters.push_back(pgroup);
18                 CommandParameter plist("list", "InputTypes", "", "", "sharedList", "sharedList", "groupList","sharedseq",false,false,true); parameters.push_back(plist);
19         CommandParameter pshared("shared", "InputTypes", "", "", "sharedList-sharedFasta", "sharedList", "none","sharedseq",false,false,true); parameters.push_back(pshared);
20                 CommandParameter poutput("output", "Multiple", "accnos-default", "default", "", "", "","",false,false); parameters.push_back(poutput);
21                 CommandParameter plabel("label", "String", "", "", "", "", "","",false,false); parameters.push_back(plabel);
22                 CommandParameter puniquegroups("uniquegroups", "String", "", "", "", "", "","",false,false,true); parameters.push_back(puniquegroups);
23                 CommandParameter psharedgroups("sharedgroups", "String", "", "", "", "", "","",false,false,true); parameters.push_back(psharedgroups);
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, "GetSharedOTUCommand", "setParameters");
33                 exit(1);
34         }
35 }
36 //**********************************************************************************************************************
37 string GetSharedOTUCommand::getHelpString(){    
38         try {
39                 string helpString = "";
40                 helpString += "The get.sharedseqs command parameters are list, group, shared, label, uniquegroups, sharedgroups, output and fasta.  The list and group or shared parameters are required, unless you have valid current files.\n";
41                 helpString += "The label parameter allows you to select what distance levels you would like output files for, and are separated by dashes.\n";
42                 helpString += "The uniquegroups and sharedgroups parameters allow you to select groups you would like to know the shared info for, and are separated by dashes.\n";
43                 helpString += "If you enter your groups under the uniquegroups parameter mothur will return the otus that contain ONLY sequences from those groups.\n";
44                 helpString += "If you enter your groups under the sharedgroups parameter mothur will return the otus that contain sequences from those groups and may also contain sequences from other groups.\n";
45                 helpString += "If you do not enter any groups then the get.sharedseqs command will return sequences that are unique to all groups in your group or shared file.\n";
46                 helpString += "The fasta parameter allows you to input a fasta file and outputs a fasta file for each distance level containing only the sequences that are in OTUs shared by the groups specified. It can only be used with a list and group file not the shared file input.\n";
47                 helpString += "The output parameter allows you to output the list of names without the group and bin number added. \n";
48                 helpString += "With this option you can use the names file as an input in get.seqs and remove.seqs commands. To do this enter output=accnos. \n";
49                 helpString += "The get.sharedseqs command outputs a .names file for each distance level containing a list of sequences in the OTUs shared by the groups specified.\n";
50                 helpString += "The get.sharedseqs command should be in the following format: get.sharedseqs(list=yourListFile, group=yourGroupFile, label=yourLabels, uniquegroups=yourGroups, fasta=yourFastafile, output=yourOutput).\n";
51                 helpString += "Example get.sharedseqs(list=amazon.fn.list, label=unique-0.01, group=amazon.groups, uniquegroups=forest-pasture, fasta=amazon.fasta, output=accnos).\n";
52                 helpString += "The output to the screen is the distance and the number of otus at that distance for the groups you specified.\n";
53                 helpString += "The default value for label is all labels in your inputfile. The default for groups is all groups in your file.\n";
54                 helpString += "Note: No spaces between parameter labels (i.e. label), '=' and parameters (i.e.yourLabel).\n";
55                 return helpString;
56         }
57         catch(exception& e) {
58                 m->errorOut(e, "GetSharedOTUCommand", "getHelpString");
59                 exit(1);
60         }
61 }
62 //**********************************************************************************************************************
63 string GetSharedOTUCommand::getOutputPattern(string type) {
64     try {
65         string pattern = "";
66
67         if (type == "fasta")            {   pattern =  "[filename],[distance],[group],shared.fasta";   }
68         else if (type == "accnos")      {   pattern =  "[filename],[distance],[group],accnos";         }
69         else if (type == "sharedseqs")  {   pattern =  "[filename],[distance],[group],shared.seqs";    }
70         else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }
71         
72         return pattern;
73     }
74     catch(exception& e) {
75         m->errorOut(e, "GetSharedOTUCommand", "getOutputPattern");
76         exit(1);
77     }
78 }
79 //**********************************************************************************************************************
80 GetSharedOTUCommand::GetSharedOTUCommand(){     
81         try {
82                 abort = true; calledHelp = true;
83                 setParameters();
84                 vector<string> tempOutNames;
85                 outputTypes["fasta"] = tempOutNames;
86                 outputTypes["accnos"] = tempOutNames;
87                 outputTypes["sharedseqs"] = tempOutNames;
88         }
89         catch(exception& e) {
90                 m->errorOut(e, "GetSharedOTUCommand", "GetSharedOTUCommand");
91                 exit(1);
92         }
93 }
94 //**********************************************************************************************************************
95 GetSharedOTUCommand::GetSharedOTUCommand(string option)  {
96         try {
97         
98                 abort = false; calledHelp = false;   
99                 unique = true;
100                 allLines = 1;
101                 
102                 //allow user to run help
103                 if(option == "help") { help(); abort = true; calledHelp = true; }
104                 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
105                 
106                 else {
107                         vector<string> myArray = setParameters();
108                         
109                         OptionParser parser(option);
110                         map<string,string> parameters = parser.getParameters();
111                         
112                         ValidParameters validParameter;
113                         map<string,string>::iterator it;
114                         
115                         //check to make sure all parameters are valid for command
116                         for (it = parameters.begin(); it != parameters.end(); it++) { 
117                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
118                         }
119                         
120                         //initialize outputTypes
121                         vector<string> tempOutNames;
122                         outputTypes["fasta"] = tempOutNames;
123                         outputTypes["accnos"] = tempOutNames;
124                         outputTypes["sharedseqs"] = tempOutNames;
125                         
126                         //if the user changes the output directory command factory will send this info to us in the output parameter 
127                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = "";         }
128                         
129                         //if the user changes the input directory command factory will send this info to us in the output parameter 
130                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
131                         if (inputDir == "not found"){   inputDir = "";          }
132                         else {
133                                 string path;
134                                 it = parameters.find("fasta");
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["fasta"] = inputDir + it->second;            }
140                                 }
141                                 
142                                 it = parameters.find("list");
143                                 //user has given a template file
144                                 if(it != parameters.end()){ 
145                                         path = m->hasPath(it->second);
146                                         //if the user has not given a path then, add inputdir. else leave path alone.
147                                         if (path == "") {       parameters["list"] = inputDir + it->second;             }
148                                 }
149                 
150                 it = parameters.find("shared");
151                                 //user has given a template file
152                                 if(it != parameters.end()){
153                                         path = m->hasPath(it->second);
154                                         //if the user has not given a path then, add inputdir. else leave path alone.
155                                         if (path == "") {       parameters["shared"] = inputDir + it->second;           }
156                                 }
157                                 
158                                 it = parameters.find("group");
159                                 //user has given a template file
160                                 if(it != parameters.end()){ 
161                                         path = m->hasPath(it->second);
162                                         //if the user has not given a path then, add inputdir. else leave path alone.
163                                         if (path == "") {       parameters["group"] = inputDir + it->second;            }
164                                 }
165                         }
166
167                         
168                         //check for required parameters
169                         listfile = validParameter.validFile(parameters, "list", true);
170                         if (listfile == "not open") { abort = true; }
171                         else if (listfile == "not found") { listfile = "";                      }
172             else {  format = "list";    m->setListFile(listfile); }
173                         
174                         groupfile = validParameter.validFile(parameters, "group", true);
175                         if (groupfile == "not open") { abort = true; }  
176                         else if (groupfile == "not found") { groupfile = ""; }
177                         else { m->setGroupFile(groupfile); }
178             
179             sharedfile = validParameter.validFile(parameters, "shared", true);
180                         if (sharedfile == "not open") { abort = true; }
181                         else if (sharedfile == "not found") { sharedfile = ""; }
182                         else { m->setSharedFile(sharedfile); }
183             
184             fastafile = validParameter.validFile(parameters, "fasta", true);
185                         if (fastafile == "not open") { abort = true; }
186                         else if (fastafile == "not found") {  fastafile = "";  }
187                         else { m->setFastaFile(fastafile); }
188
189             
190             if ((sharedfile == "") && (listfile == "")) { //look for currents
191                 //is there are current file available for either of these?
192                                 //give priority to shared, then list
193                                 sharedfile = m->getSharedFile();
194                                 if (sharedfile != "") {  m->mothurOut("Using " + sharedfile + " as input file for the shared parameter."); m->mothurOutEndLine(); }
195                                 else {
196                                         listfile = m->getListFile();
197                                         if (listfile != "") {  m->mothurOut("Using " + listfile + " as input file for the list parameter."); m->mothurOutEndLine(); }
198                                         else {
199                                                 m->mothurOut("No valid current files. You must provide a shared or list file."); m->mothurOutEndLine();
200                                                 abort = true;
201                                         }
202                                 }
203             }else if ((sharedfile != "") && (listfile != "")) {
204                 m->mothurOut("You may enter ONLY ONE of the following: shared or list."); m->mothurOutEndLine(); abort = true;
205             }
206                         
207             if (listfile != "") {
208                                 if (groupfile == ""){
209                                         groupfile = m->getGroupFile();
210                                         if (groupfile != "") {  m->mothurOut("Using " + groupfile + " as input file for the group parameter."); m->mothurOutEndLine(); }
211                                         else { m->mothurOut("You need to provide a group file if you are going to use the list format."); m->mothurOutEndLine(); abort = true;
212                                         }
213                                 }
214                         }
215
216                         if ((sharedfile != "") && (fastafile != "")) { m->mothurOut("You cannot use the fasta file with the shared file."); m->mothurOutEndLine(); abort = true; }
217             
218                         //check for optional parameter and set defaults
219                         // ...at some point should added some additional type checking...
220                         label = validParameter.validFile(parameters, "label", false);                   
221                         if (label == "not found") { label = ""; }
222                         else { 
223                                 if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }
224                                 else { allLines = 1;  }
225                         }
226                         
227                         output = validParameter.validFile(parameters, "output", false);                 
228                         if (output == "not found") { output = ""; }
229                         else if (output == "default") { output = ""; }
230                         
231                         groups = validParameter.validFile(parameters, "uniquegroups", false);                   
232                         if (groups == "not found") { groups = ""; }
233                         else { 
234                                 userGroups = "unique." + groups;
235                                 m->splitAtDash(groups, Groups);
236                         }
237                         
238                         groups = validParameter.validFile(parameters, "sharedgroups", false);                   
239                         if (groups == "not found") { groups = "";  }
240                         else { 
241                                 userGroups = groups;
242                                 m->splitAtDash(groups, Groups);
243                                 unique = false;
244                         }
245                         
246         }
247
248         }
249         catch(exception& e) {
250                 m->errorOut(e, "GetSharedOTUCommand", "GetSharedOTUCommand");
251                 exit(1);
252         }
253 }
254 //**********************************************************************************************************************
255
256 int GetSharedOTUCommand::execute(){
257         try {
258                 
259                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
260                 
261         if ( sharedfile != "") { runShared(); }
262         else {
263             m->setGroups(Groups);
264             groupMap = new GroupMap(groupfile);
265             int error = groupMap->readMap();
266             if (error == 1) { delete groupMap; return 0; }
267             
268             if (m->control_pressed) { delete groupMap; return 0; }
269             
270             if (Groups.size() == 0) {
271                 Groups = groupMap->getNamesOfGroups();
272                 
273                 //make string for outputfile name
274                 userGroups = "unique.";
275                 for(int i = 0; i < Groups.size(); i++) {  userGroups += Groups[i] + "-";  }
276                 userGroups = userGroups.substr(0, userGroups.length()-1);
277             }else{
278                 //sanity check for group names
279                 SharedUtil util;
280                 vector<string> namesOfGroups = groupMap->getNamesOfGroups(); 
281                 util.setGroups(Groups, namesOfGroups);
282                 groupMap->setNamesOfGroups(namesOfGroups);
283             }
284         
285             //put groups in map to find easier
286             for(int i = 0; i < Groups.size(); i++) {
287                 groupFinder[Groups[i]] = Groups[i];
288             }
289             
290             if (fastafile != "") {
291                 ifstream inFasta;
292                 m->openInputFile(fastafile, inFasta);
293                 
294                 while(!inFasta.eof()) {
295                     if (m->control_pressed) { outputTypes.clear(); inFasta.close(); delete groupMap; return 0; }
296                     
297                     Sequence seq(inFasta); m->gobble(inFasta);
298                     if (seq.getName() != "") {  seqs.push_back(seq);   }
299                 }
300                 inFasta.close();
301             }
302             
303             ListVector* lastlist = NULL;
304             string lastLabel = "";
305             
306             //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
307             set<string> processedLabels;
308             set<string> userLabels = labels;
309             
310             ifstream in;
311             m->openInputFile(listfile, in);
312             
313             //as long as you are not at the end of the file or done wih the lines you want
314             while((!in.eof()) && ((allLines == 1) || (userLabels.size() != 0))) {
315                 
316                 if (m->control_pressed) { 
317                     if (lastlist != NULL) {             delete lastlist;        }
318                     for (int i = 0; i < outputNames.size(); i++) {      m->mothurRemove(outputNames[i]); }  outputTypes.clear();
319                     delete groupMap; return 0;
320                 }
321                 
322                 list = new ListVector(in);
323                 
324                 if(allLines == 1 || labels.count(list->getLabel()) == 1){                       
325                     m->mothurOut(list->getLabel()); 
326                     process(list);
327                     
328                     processedLabels.insert(list->getLabel());
329                     userLabels.erase(list->getLabel());
330                 }
331                 
332                 if ((m->anyLabelsToProcess(list->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
333                         string saveLabel = list->getLabel();
334                         
335                         m->mothurOut(lastlist->getLabel()); 
336                         process(lastlist);
337                         
338                         processedLabels.insert(lastlist->getLabel());
339                         userLabels.erase(lastlist->getLabel());
340                         
341                         //restore real lastlabel to save below
342                         list->setLabel(saveLabel);
343                 }
344
345                 lastLabel = list->getLabel();
346                 
347                 if (lastlist != NULL) {         delete lastlist;        }
348                 lastlist = list;                        
349             }
350             
351             in.close();
352             
353             //output error messages about any remaining user labels
354             set<string>::iterator it;
355             bool needToRun = false;
356             for (it = userLabels.begin(); it != userLabels.end(); it++) {  
357                 m->mothurOut("Your file does not include the label " + *it); 
358                 if (processedLabels.count(lastLabel) != 1) {
359                     m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
360                     needToRun = true;
361                 }else {
362                     m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
363                 }
364             }
365             
366             //run last label if you need to
367             if (needToRun == true)  {
368                     m->mothurOut(lastlist->getLabel()); 
369                     process(lastlist);
370                         
371                     processedLabels.insert(lastlist->getLabel());
372                     userLabels.erase(lastlist->getLabel());
373             }
374             
375
376             //reset groups parameter
377             m->clearGroups();  
378             
379             if (lastlist != NULL) {             delete lastlist;        }
380             
381             if (m->control_pressed) { outputTypes.clear(); for (int i = 0; i < outputNames.size(); i++) {       m->mothurRemove(outputNames[i]); }  delete groupMap; return 0; } 
382                 }
383                 //set fasta file as new current fastafile
384                 string current = "";
385                 itTypes = outputTypes.find("fasta");
386                 if (itTypes != outputTypes.end()) {
387                         if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFastaFile(current); }
388                 }
389                 
390                 if (output == "accnos") {
391                         itTypes = outputTypes.find("accnos");
392                         if (itTypes != outputTypes.end()) {
393                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setAccnosFile(current); }
394                         }
395                 }
396                 
397                 m->mothurOutEndLine();
398                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
399                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
400                 m->mothurOutEndLine();
401
402
403                 return 0;
404         }
405
406         catch(exception& e) {
407                 m->errorOut(e, "GetSharedOTUCommand", "execute");
408                 exit(1);
409         }
410 }
411 /***********************************************************/
412 int GetSharedOTUCommand::process(ListVector* shared) {
413         try {
414                 
415                 map<string, string> fastaMap;
416                 
417                 ofstream outNames;
418                 string outputFileNames;
419                 
420                 if (outputDir == "") { outputDir += m->hasPath(listfile); }
421         map<string, string> variables;
422         variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(listfile));
423         variables["[distance]"] = shared->getLabel();
424         variables["[group]"] = userGroups;
425                 if (output != "accnos") { outputFileNames = getOutputFileName("sharedseqs", variables); }
426                 else { outputFileNames = getOutputFileName("accnos", variables); }
427         
428                 m->openOutputFile(outputFileNames, outNames);
429                 
430                 bool wroteSomething = false;
431                 int num = 0;
432                                 
433                 //go through each bin, find out if shared
434                 for (int i = 0; i < shared->getNumBins(); i++) {
435                         if (m->control_pressed) { outNames.close(); m->mothurRemove(outputFileNames); return 0; }
436                         
437                         bool uniqueOTU = true;
438                         
439                         map<string, int> atLeastOne;
440                         for (int f = 0; f < Groups.size(); f++) {
441                                 atLeastOne[Groups[f]] = 0;
442                         }
443                         
444                         vector<string> namesOfSeqsInThisBin;
445                         
446                         string names = shared->get(i); 
447             vector<string> binNames;
448             m->splitAtComma(names, binNames);
449                         for(int j = 0; j < binNames.size(); j++) {
450                                 string name = binNames[j];
451                                 
452                                 //find group
453                                 string seqGroup = groupMap->getGroup(name);
454                                 if (output != "accnos") {
455                                         namesOfSeqsInThisBin.push_back((name + "|" + seqGroup + "|" + toString(i+1)));
456                                 }else {  namesOfSeqsInThisBin.push_back(name);  }
457                                 
458                                 if (seqGroup == "not found") { m->mothurOut(name + " is not in your groupfile. Please correct."); m->mothurOutEndLine(); exit(1);  }
459                                 
460                                 //is this seq in one of hte groups we care about
461                                 it = groupFinder.find(seqGroup);
462                                 if (it == groupFinder.end()) {  uniqueOTU = false;  } //you have a sequence from a group you don't want
463                                 else {  atLeastOne[seqGroup]++;  }
464                         }
465                         
466                         //make sure you have at least one seq from each group you want
467                         bool sharedByAll = true;
468                         map<string, int>::iterator it2;
469                         for (it2 = atLeastOne.begin(); it2 != atLeastOne.end(); it2++) {
470                                 if (it2->second == 0) {  sharedByAll = false;   }
471                         }
472                         
473                         //if the user wants unique bins and this is unique then print
474                         //or this the user wants shared bins and this bin is shared then print
475                         if ((unique && uniqueOTU && sharedByAll) || (!unique && sharedByAll)) {
476                                 
477                                 wroteSomething = true;
478                                 num++;
479                                 
480                                 //output list of names 
481                                 for (int j = 0; j < namesOfSeqsInThisBin.size(); j++) {
482                                         outNames << namesOfSeqsInThisBin[j] << endl;
483                                         
484                                         if (fastafile != "") { 
485                                                 if (output != "accnos") {
486                                                         string seqName = namesOfSeqsInThisBin[j].substr(0,namesOfSeqsInThisBin[j].find_last_of('|'));
487                                                         seqName = seqName.substr(0,seqName.find_last_of('|'));
488                                                         fastaMap[seqName] = namesOfSeqsInThisBin[j];  //fastaMap needs to contain just the seq name for output later
489                                                 }else {
490                                                         fastaMap[namesOfSeqsInThisBin[j]] = namesOfSeqsInThisBin[j];
491                                                 }
492                                         }
493                                 }
494                         }
495                 }
496                 
497                 outNames.close();
498                 
499                 if (!wroteSomething) {
500                         m->mothurRemove(outputFileNames);
501                         string outputString = "\t" + toString(num) + " - No otus shared by groups";
502                         
503                         string groupString = "";
504                         for (int h = 0; h < Groups.size(); h++) {
505                                 groupString += "  " + Groups[h];
506                         }
507                         
508                         outputString += groupString + ".";
509                         m->mothurOut(outputString); m->mothurOutEndLine();
510                 }else { 
511                         m->mothurOut("\t" + toString(num)); m->mothurOutEndLine(); 
512                         outputNames.push_back(outputFileNames);
513                         if (output != "accnos") { outputTypes["sharedseqs"].push_back(outputFileNames); }
514                         else { outputTypes["accnos"].push_back(outputFileNames); }
515                 }
516                 
517                 //if fasta file provided output new fasta file
518                 if ((fastafile != "") && wroteSomething) {
519                         if (outputDir == "") { outputDir += m->hasPath(fastafile); }
520             variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(fastafile));
521                         string outputFileFasta = getOutputFileName("fasta", variables);
522                         ofstream outFasta;
523                         m->openOutputFile(outputFileFasta, outFasta);
524                         outputNames.push_back(outputFileFasta); outputTypes["fasta"].push_back(outputFileFasta);
525                         
526                         for (int k = 0; k < seqs.size(); k++) {
527                                 if (m->control_pressed) { outFasta.close(); return 0; }
528                         
529                                 //if this is a sequence we want, output it
530                                 it = fastaMap.find(seqs[k].getName());
531                                 if (it != fastaMap.end()) {
532                                 
533                                         if (output != "accnos") {
534                                                 outFasta << ">" << it->second << endl;
535                                         }else {
536                                                 outFasta << ">" << it->first << endl;
537                                         }
538                                         
539                                         outFasta << seqs[k].getAligned() << endl;
540                                 }
541                         }
542                         
543                         outFasta.close();
544                 }
545                 
546                 return 0;
547                 
548         }
549         catch(exception& e) {
550                 m->errorOut(e, "GetSharedOTUCommand", "process");
551                 exit(1);
552         }
553 }
554 /***********************************************************/
555 int GetSharedOTUCommand::runShared() {
556         try {
557         InputData input(sharedfile, "sharedfile");
558                 vector<SharedRAbundVector*> lookup = input.getSharedRAbundVectors();
559                 string lastLabel = lookup[0]->getLabel();
560         
561         if (Groups.size() == 0) {
562             Groups = m->getGroups();
563             
564             //make string for outputfile name
565             userGroups = "unique.";
566             for(int i = 0; i < Groups.size(); i++) {  userGroups += Groups[i] + "-";  }
567             userGroups = userGroups.substr(0, userGroups.length()-1);
568         }else {
569             //sanity check for group names
570             SharedUtil util;
571             vector<string> allGroups = m->getAllGroups();
572             util.setGroups(Groups, allGroups);
573         }
574         
575         //put groups in map to find easier
576         for(int i = 0; i < Groups.size(); i++) {
577             groupFinder[Groups[i]] = Groups[i];
578         }
579
580                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
581                 set<string> processedLabels;
582                 set<string> userLabels = labels;
583         
584                 //as long as you are not at the end of the file or done wih the lines you want
585                 while((lookup[0] != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
586                         if (m->control_pressed) {
587                 outputTypes.clear(); for (int i = 0; i < outputNames.size(); i++) {     m->mothurRemove(outputNames[i]); }
588                 for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; } m->clearGroups(); return 0;
589                         }
590             
591             
592                         if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){
593                                 m->mothurOut(lookup[0]->getLabel()); 
594                                 process(lookup);
595                                 
596                                 processedLabels.insert(lookup[0]->getLabel());
597                                 userLabels.erase(lookup[0]->getLabel());
598                         }
599                         
600                         if ((m->anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
601                 string saveLabel = lookup[0]->getLabel();
602                 
603                 for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }
604                 lookup = input.getSharedRAbundVectors(lastLabel);
605                 
606                 m->mothurOut(lookup[0]->getLabel()); 
607                 process(lookup);
608                 
609                 processedLabels.insert(lookup[0]->getLabel());
610                 userLabels.erase(lookup[0]->getLabel());
611                 
612                 //restore real lastlabel to save below
613                 lookup[0]->setLabel(saveLabel);
614                         }
615                         
616                         lastLabel = lookup[0]->getLabel();
617             
618                         //get next line to process
619                         //prevent memory leak
620                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }
621                         lookup = input.getSharedRAbundVectors();
622                 }
623                 
624                 if (m->control_pressed) {
625             outputTypes.clear(); for (int i = 0; i < outputNames.size(); i++) { m->mothurRemove(outputNames[i]); }
626             for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; } m->clearGroups(); return 0;
627         }
628         
629                 //output error messages about any remaining user labels
630                 set<string>::iterator it;
631                 bool needToRun = false;
632                 for (it = userLabels.begin(); it != userLabels.end(); it++) {
633                         m->mothurOut("Your file does not include the label " + *it);
634                         if (processedLabels.count(lastLabel) != 1) {
635                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
636                                 needToRun = true;
637                         }else {
638                                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
639                         }
640                 }
641                 
642                 //run last label if you need to
643                 if (needToRun == true)  {
644             for (int i = 0; i < lookup.size(); i++) {  if (lookup[i] != NULL) { delete lookup[i];       } }
645             lookup = input.getSharedRAbundVectors(lastLabel);
646             
647             m->mothurOut(lookup[0]->getLabel()); 
648             process(lookup);
649             for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
650                 }
651         
652                 //reset groups parameter
653                 m->clearGroups();  
654                 
655                 return 0;
656
657     }
658         catch(exception& e) {
659                 m->errorOut(e, "GetSharedOTUCommand", "runShared");
660                 exit(1);
661         }
662 }
663 /***********************************************************/
664 int GetSharedOTUCommand::process(vector<SharedRAbundVector*>& lookup) {
665         try {
666                 
667                 string outputFileNames;
668                 if (outputDir == "") { outputDir += m->hasPath(sharedfile); }
669         map<string, string> variables;
670         variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(sharedfile));
671         variables["[distance]"] = lookup[0]->getLabel();
672         variables["[group]"] = userGroups;
673                 if (output != "accnos") { outputFileNames = getOutputFileName("sharedseqs", variables); }
674                 else { outputFileNames = getOutputFileName("accnos", variables); }
675         
676         ofstream outNames;
677                 m->openOutputFile(outputFileNames, outNames);
678                 
679                 bool wroteSomething = false;
680                 int num = 0;
681         
682                 //go through each bin, find out if shared
683                 for (int i = 0; i < lookup[0]->getNumBins(); i++) {
684                         if (m->control_pressed) { outNames.close(); m->mothurRemove(outputFileNames); return 0; }
685                         
686                         bool uniqueOTU = true;
687                         map<string, int> atLeastOne;
688                         for (int f = 0; f < Groups.size(); f++) {  atLeastOne[Groups[f]] = 0;  }
689                         
690                         set<string> namesOfGroupsInThisBin;
691                         
692                         for(int j = 0; j < lookup.size(); j++) {
693                                 string seqGroup = lookup[j]->getGroup();
694                 string name = m->currentBinLabels[i];
695                                 
696                 if (lookup[j]->getAbundance(i) != 0) {
697                     if (output != "accnos") {
698                         namesOfGroupsInThisBin.insert(name + "|" + seqGroup + "|" + toString(lookup[j]->getAbundance(i)));
699                     }else {  namesOfGroupsInThisBin.insert(name);       }
700                     
701                     //is this seq in one of the groups we care about
702                     it = groupFinder.find(seqGroup);
703                     if (it == groupFinder.end()) {  uniqueOTU = false;  } //you have sequences from a group you don't want
704                     else {  atLeastOne[seqGroup]++;  }
705                                 }
706                         }
707                         
708                         //make sure you have at least one seq from each group you want
709                         bool sharedByAll = true;
710                         map<string, int>::iterator it2;
711                         for (it2 = atLeastOne.begin(); it2 != atLeastOne.end(); it2++) {
712                                 if (it2->second == 0) {  sharedByAll = false;   }
713                         }
714                         
715                         //if the user wants unique bins and this is unique then print
716                         //or this the user wants shared bins and this bin is shared then print
717                         if ((unique && uniqueOTU && sharedByAll) || (!unique && sharedByAll)) {
718                                 
719                                 wroteSomething = true;
720                                 num++;
721                                 
722                                 //output list of names
723                                 for (set<string>::iterator itNames = namesOfGroupsInThisBin.begin(); itNames != namesOfGroupsInThisBin.end(); itNames++) {
724                                         outNames << (*itNames) << endl;
725                                 }
726                         }
727                 }
728                 outNames.close();
729                 
730                 if (!wroteSomething) {
731                         m->mothurRemove(outputFileNames);
732                         string outputString = "\t" + toString(num) + " - No otus shared by groups";
733                         
734                         string groupString = "";
735                         for (int h = 0; h < Groups.size(); h++) {
736                                 groupString += "  " + Groups[h];
737                         }
738                         
739                         outputString += groupString + ".";
740                         m->mothurOut(outputString); m->mothurOutEndLine();
741                 }else {
742                         m->mothurOut("\t" + toString(num)); m->mothurOutEndLine();
743                         outputNames.push_back(outputFileNames);
744                         if (output != "accnos") { outputTypes["sharedseqs"].push_back(outputFileNames); }
745                         else { outputTypes["accnos"].push_back(outputFileNames); }
746                 }
747                 
748                 return 0;
749         }
750         catch(exception& e) {
751                 m->errorOut(e, "GetSharedOTUCommand", "process");
752                 exit(1);
753         }
754 }
755
756 //**********************************************************************************************************************