]> git.donarmstrong.com Git - mothur.git/blob - removerarecommand.cpp
added headers to shared and relabund files
[mothur.git] / removerarecommand.cpp
1 /*
2  *  removerarecommand.cpp
3  *  mothur
4  *
5  *  Created by westcott on 1/21/11.
6  *  Copyright 2011 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "removerarecommand.h"
11 #include "sequence.hpp"
12 #include "groupmap.h"
13 #include "sharedutilities.h"
14 #include "inputdata.h"
15
16 //**********************************************************************************************************************
17 vector<string> RemoveRareCommand::setParameters(){      
18         try {
19                 CommandParameter plist("list", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(plist);
20                 CommandParameter prabund("rabund", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(prabund);
21                 CommandParameter psabund("sabund", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(psabund);
22                 CommandParameter pshared("shared", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(pshared);
23                 CommandParameter pgroup("group", "InputTypes", "", "", "none", "none", "none",false,true); parameters.push_back(pgroup);
24                 CommandParameter pgroups("groups", "String", "", "", "", "", "",false,false); parameters.push_back(pgroups);
25                 CommandParameter plabel("label", "String", "", "", "", "", "",false,false); parameters.push_back(plabel);
26                 CommandParameter pnseqs("nseqs", "Number", "", "0", "", "", "",false,true); parameters.push_back(pnseqs);
27                 CommandParameter pbygroup("bygroup", "Boolean", "", "f", "", "", "",false,true); parameters.push_back(pbygroup);
28                 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "",false,false); parameters.push_back(pinputdir);
29                 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "",false,false); parameters.push_back(poutputdir);
30                 
31                 vector<string> myArray;
32                 for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
33                 return myArray;
34         }
35         catch(exception& e) {
36                 m->errorOut(e, "RemoveRareCommand", "setParameters");
37                 exit(1);
38         }
39 }
40 //**********************************************************************************************************************
41 string RemoveRareCommand::getHelpString(){      
42         try {
43                 string helpString = "";
44                 helpString += "The remove.rare command parameters are list, rabund, sabund, shared, group, label, groups, bygroup and nseqs.\n";
45                 helpString += "The remove.rare command reads one of the following file types: list, rabund, sabund or shared file. It outputs a new file after removing the rare otus.\n";
46                 helpString += "The groups parameter allows you to specify which of the groups you would like analyzed.  Default=all. You may separate group names with dashes.\n";
47                 helpString += "The label parameter is used to analyze specific labels in your input. default=all. You may separate label names with dashes.\n";
48                 helpString += "The bygroup parameter is only valid with the shared file. default=f, meaning remove any OTU that has nseqs or fewer sequences across all groups.\n";
49                 helpString += "bygroups=T means remove any OTU that has nseqs or fewer sequences in each group (if groupA has 1 sequence and group B has 100 sequences in OTUZ and nseqs=1, then set the groupA count for OTUZ to 0 and keep groupB's count at 100.) \n";
50                 helpString += "The nseqs parameter allows you to set the cutoff for an otu to be deemed rare. It is required.\n";
51                 helpString += "The remove.rare command should be in the following format: remove.rare(shared=yourSharedFile, nseqs=yourRareCutoff).\n";
52                 helpString += "Example remove.rare(shared=amazon.fn.shared, nseqs=2).\n";
53                 helpString += "Note: No spaces between parameter labels (i.e. shared), '=' and parameters (i.e.yourSharedFile).\n";
54                 return helpString;
55         }
56         catch(exception& e) {
57                 m->errorOut(e, "RemoveRareCommand", "getHelpString");
58                 exit(1);
59         }
60 }
61 //**********************************************************************************************************************
62 RemoveRareCommand::RemoveRareCommand(){ 
63         try {
64                 abort = true; calledHelp = true; 
65                 setParameters();
66                 vector<string> tempOutNames;
67                 outputTypes["rabund"] = tempOutNames;
68                 outputTypes["sabund"] = tempOutNames;
69                 outputTypes["list"] = tempOutNames;
70                 outputTypes["group"] = tempOutNames;
71                 outputTypes["shared"] = tempOutNames;
72         }
73         catch(exception& e) {
74                 m->errorOut(e, "RemoveRareCommand", "RemoveRareCommand");
75                 exit(1);
76         }
77 }
78 //**********************************************************************************************************************
79 RemoveRareCommand::RemoveRareCommand(string option)  {
80         try {
81                 abort = false; calledHelp = false;   
82                 allLines = 1;
83                 
84                 //allow user to run help
85                 if(option == "help") { help(); abort = true; calledHelp = true; }
86                 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
87                 
88                 else {
89                         vector<string> myArray = setParameters();
90                         
91                         OptionParser parser(option);
92                         map<string,string> parameters = parser.getParameters();
93                         
94                         ValidParameters validParameter;
95                         map<string,string>::iterator it;
96                         
97                         //check to make sure all parameters are valid for command
98                         for (it = parameters.begin(); it != parameters.end(); it++) { 
99                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
100                         }
101                         
102                         //initialize outputTypes
103                         vector<string> tempOutNames;
104                         outputTypes["rabund"] = tempOutNames;
105                         outputTypes["sabund"] = tempOutNames;
106                         outputTypes["list"] = tempOutNames;
107                         outputTypes["group"] = tempOutNames;
108                         outputTypes["shared"] = tempOutNames;   
109                         
110                         //if the user changes the output directory command factory will send this info to us in the output parameter 
111                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = "";         }
112                         
113                         //if the user changes the input directory command factory will send this info to us in the output parameter 
114                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
115                         if (inputDir == "not found"){   inputDir = "";          }
116                         else {
117                                 string path;
118                                 it = parameters.find("list");
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["list"] = inputDir + it->second;             }
124                                 }
125                                 
126                                 it = parameters.find("group");
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["group"] = inputDir + it->second;            }
132                                 }
133                                 
134                                 it = parameters.find("sabund");
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["sabund"] = inputDir + it->second;           }
140                                 }
141                                 
142                                 it = parameters.find("rabund");
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["rabund"] = 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                         
159                         
160                         //check for file parameters
161                         listfile = validParameter.validFile(parameters, "list", true);
162                         if (listfile == "not open") { abort = true; }
163                         else if (listfile == "not found") {  listfile = "";  }  
164                         
165                         sabundfile = validParameter.validFile(parameters, "sabund", true);
166                         if (sabundfile == "not open") { abort = true; }
167                         else if (sabundfile == "not found") {  sabundfile = "";  }      
168                         
169                         rabundfile = validParameter.validFile(parameters, "rabund", true);
170                         if (rabundfile == "not open") { abort = true; }
171                         else if (rabundfile == "not found") {  rabundfile = "";  }                              
172                         
173                         groupfile = validParameter.validFile(parameters, "group", true);
174                         if (groupfile == "not open") { groupfile = ""; abort = true; }
175                         else if (groupfile == "not found") {  groupfile = "";  }        
176                         
177                         sharedfile = validParameter.validFile(parameters, "shared", true);
178                         if (sharedfile == "not open") { sharedfile = "";  abort = true; }
179                         else if (sharedfile == "not found") {  sharedfile = "";  }
180                         
181                         if ((sharedfile == "") && (listfile == "") && (rabundfile == "") && (sabundfile == "")) { 
182                                 //is there are current file available for any of these?
183                                 //give priority to shared, then list, then rabund, then sabund
184                                 //if there is a current shared file, use it
185                                 sharedfile = m->getSharedFile(); 
186                                 if (sharedfile != "") {  m->mothurOut("Using " + sharedfile + " as input file for the shared parameter."); m->mothurOutEndLine(); }
187                                 else { 
188                                         listfile = m->getListFile(); 
189                                         if (listfile != "") {  m->mothurOut("Using " + listfile + " as input file for the list parameter."); m->mothurOutEndLine(); }
190                                         else { 
191                                                 rabundfile = m->getRabundFile(); 
192                                                 if (rabundfile != "") {  m->mothurOut("Using " + rabundfile + " as input file for the rabund parameter."); m->mothurOutEndLine(); }
193                                                 else { 
194                                                         sabundfile = m->getSabundFile(); 
195                                                         if (sabundfile != "") {  m->mothurOut("Using " + sabundfile + " as input file for the sabund parameter."); m->mothurOutEndLine(); }
196                                                         else { 
197                                                                 m->mothurOut("No valid current files. You must provide a list, sabund, rabund or shared file."); m->mothurOutEndLine(); 
198                                                                 abort = true;
199                                                         }
200                                                 }
201                                         }
202                                 }
203                         } 
204                         
205                         groups = validParameter.validFile(parameters, "groups", false);                 
206                         if (groups == "not found") { groups = "all"; }
207                         m->splitAtDash(groups, Groups);
208                         
209                         label = validParameter.validFile(parameters, "label", false);                   
210                         if (label == "not found") { label = ""; }
211                         else { 
212                                 if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }
213                                 else { allLines = 1;  }
214                         }
215                         
216                         string temp = validParameter.validFile(parameters, "nseqs", false);      
217                         if (temp == "not found") { m->mothurOut("nseqs is a required parameter."); m->mothurOutEndLine(); abort = true; }
218                         else { convert(temp, nseqs); }
219                         
220                         temp = validParameter.validFile(parameters, "bygroup", false);   if (temp == "not found") { temp = "f"; }
221                         byGroup = m->isTrue(temp);
222                         
223                         if (byGroup && (sharedfile == "")) { m->mothurOut("The byGroup parameter is only valid with a shared file."); m->mothurOutEndLine(); }
224                         
225                         if ((groupfile != "") && (listfile == "")) { m->mothurOut("A groupfile is only valid with a list file."); m->mothurOutEndLine(); groupfile = ""; }
226                 }
227                 
228         }
229         catch(exception& e) {
230                 m->errorOut(e, "RemoveRareCommand", "RemoveRareCommand");
231                 exit(1);
232         }
233 }
234 //**********************************************************************************************************************
235
236 int RemoveRareCommand::execute(){
237         try {
238                 
239                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
240                 
241                 if (m->control_pressed) { return 0; }
242                 
243                 //read through the correct file and output lines you want to keep
244                 if (sabundfile != "")           {               processSabund();        }
245                 if (rabundfile != "")           {               processRabund();        }
246                 if (listfile != "")                     {               processList();          }
247                 if (sharedfile != "")           {               processShared();        }
248                 
249                 if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) {        remove(outputNames[i].c_str()); } return 0; }
250                         
251                 if (outputNames.size() != 0) {
252                         m->mothurOutEndLine();
253                         m->mothurOut("Output File Names: "); m->mothurOutEndLine();
254                         for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
255                         m->mothurOutEndLine();
256                         
257                         //set rabund file as new current rabundfile
258                         string current = "";
259                         itTypes = outputTypes.find("rabund");
260                         if (itTypes != outputTypes.end()) {
261                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setRabundFile(current); }
262                         }
263                         
264                         itTypes = outputTypes.find("sabund");
265                         if (itTypes != outputTypes.end()) {
266                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setSabundFile(current); }
267                         }
268                         
269                         itTypes = outputTypes.find("group");
270                         if (itTypes != outputTypes.end()) {
271                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setGroupFile(current); }
272                         }
273                         
274                         itTypes = outputTypes.find("list");
275                         if (itTypes != outputTypes.end()) {
276                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setListFile(current); }
277                         }
278                         
279                         itTypes = outputTypes.find("shared");
280                         if (itTypes != outputTypes.end()) {
281                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setSharedFile(current); }
282                         }
283                 }
284                 
285                 return 0;               
286         }
287         
288         catch(exception& e) {
289                 m->errorOut(e, "RemoveRareCommand", "execute");
290                 exit(1);
291         }
292 }
293
294 //**********************************************************************************************************************
295 int RemoveRareCommand::processList(){
296         try {
297                 string thisOutputDir = outputDir;
298                 if (outputDir == "") {  thisOutputDir += m->hasPath(listfile);  }
299                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(listfile)) + "pick" +  m->getExtension(listfile);
300                 string outputGroupFileName = thisOutputDir + m->getRootName(m->getSimpleName(groupfile)) + "pick" +  m->getExtension(groupfile);
301                 
302                 ofstream out, outGroup;
303                 m->openOutputFile(outputFileName, out);
304                 
305                 bool wroteSomething = false;
306                 
307                 //you must provide a label because the names in the listfile need to be consistent
308                 string thisLabel = "";
309                 if (allLines) { m->mothurOut("For the listfile you must select one label, using first label in your listfile."); m->mothurOutEndLine(); }
310                 else if (labels.size() > 1) { m->mothurOut("For the listfile you must select one label, using " + (*labels.begin()) + "."); m->mothurOutEndLine(); thisLabel = *labels.begin(); }
311                 else { thisLabel = *labels.begin(); }
312                 
313                 InputData input(listfile, "list");
314                 ListVector* list = input.getListVector();
315                 
316                 //get first one or the one we want
317                 if (thisLabel != "") {  
318                         //use smart distancing
319                         set<string> userLabels; userLabels.insert(thisLabel);
320                         set<string> processedLabels;
321                         string lastLabel = list->getLabel();
322                         while((list != NULL) && (userLabels.size() != 0)) {
323                                 if(userLabels.count(list->getLabel()) == 1){
324                                         processedLabels.insert(list->getLabel());
325                                         userLabels.erase(list->getLabel());
326                                         break;
327                                 }
328                                 
329                                 if ((m->anyLabelsToProcess(list->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
330                                         processedLabels.insert(list->getLabel());
331                                         userLabels.erase(list->getLabel());
332                                         delete list;
333                                         list = input.getListVector(lastLabel);
334                                         break;
335                                 }
336                                 lastLabel = list->getLabel();
337                                 delete list;
338                                 list = input.getListVector();
339                         }
340                         if (userLabels.size() != 0) { 
341                                 m->mothurOut("Your file does not include the label " + thisLabel + ". I will use " + lastLabel + ".");  m->mothurOutEndLine();
342                                 list = input.getListVector(lastLabel); 
343                         }
344                 }
345                 
346                 //if groupfile is given then use it
347                 GroupMap* groupMap;
348                 if (groupfile != "") { 
349                         groupMap = new GroupMap(groupfile); groupMap->readMap(); 
350                         SharedUtil util;
351                         util.setGroups(Groups, groupMap->namesOfGroups);
352                         m->openOutputFile(outputGroupFileName, outGroup);
353                 }
354                 
355                 
356                 if (list != NULL) {     
357                         //make a new list vector
358                         ListVector newList;
359                         newList.setLabel(list->getLabel());
360                         
361                         //for each bin
362                         for (int i = 0; i < list->getNumBins(); i++) {
363                                 if (m->control_pressed) {  if (groupfile != "") { delete groupMap; outGroup.close(); remove(outputGroupFileName.c_str()); } out.close();  remove(outputFileName.c_str());  return 0; }
364                                 
365                                 //parse out names that are in accnos file
366                                 string binnames = list->get(i);
367                                 vector<string> names;
368                                 string saveBinNames = binnames;
369                                 m->splitAtComma(binnames, names);
370                                 
371                                 vector<string> newGroupFile;
372                                 if (groupfile != "") {
373                                         vector<string> newNames;
374                                         saveBinNames = "";
375                                         for(int k = 0; k < names.size(); k++) {
376                                                 string group = groupMap->getGroup(names[k]);
377                                                 
378                                                 if (m->inUsersGroups(group, Groups)) {
379                                                         newGroupFile.push_back(names[k] + "\t" + group); 
380                                                                 
381                                                         newNames.push_back(names[k]);   
382                                                         saveBinNames += names[k] + ",";
383                                                 }
384                                         }
385                                         names = newNames;
386                                         saveBinNames = saveBinNames.substr(0, saveBinNames.length()-1);
387                                 }
388
389                                 if (names.size() > nseqs) { //keep bin
390                                         newList.push_back(saveBinNames);
391                                         for(int k = 0; k < newGroupFile.size(); k++) { outGroup << newGroupFile[k] << endl; }
392                                 }
393                         }
394                         
395                         //print new listvector
396                         if (newList.getNumBins() != 0) {
397                                 wroteSomething = true;
398                                 newList.print(out);
399                         }
400                 }       
401                 
402                 out.close();
403                 if (groupfile != "") { outGroup.close(); outputTypes["group"].push_back(outputGroupFileName); outputNames.push_back(outputGroupFileName); }
404                 
405                 if (wroteSomething == false) {  m->mothurOut("Your file contains only rare sequences."); m->mothurOutEndLine();  }
406                 outputTypes["list"].push_back(outputFileName); outputNames.push_back(outputFileName);
407                 
408                 return 0;
409         }
410         catch(exception& e) {
411                 m->errorOut(e, "RemoveRareCommand", "processList");
412                 exit(1);
413         }
414 }
415 //**********************************************************************************************************************
416 int RemoveRareCommand::processSabund(){
417         try {
418                 string thisOutputDir = outputDir;
419                 if (outputDir == "") {  thisOutputDir += m->hasPath(sabundfile);  }
420                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(sabundfile)) + "pick" +  m->getExtension(sabundfile);
421                 outputTypes["sabund"].push_back(outputFileName); outputNames.push_back(outputFileName);
422
423                 ofstream out;
424                 m->openOutputFile(outputFileName, out);
425                 
426                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
427                 InputData input(sabundfile, "sabund");
428                 SAbundVector* sabund = input.getSAbundVector();
429                 string lastLabel = sabund->getLabel();
430                 set<string> processedLabels;
431                 set<string> userLabels = labels;
432                 
433                 while((sabund != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
434                         
435                         if (m->control_pressed) { delete sabund; out.close(); return 0; }
436                         
437                         if(allLines == 1 || labels.count(sabund->getLabel()) == 1){                     
438                                 
439                                 m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
440                                 processedLabels.insert(sabund->getLabel());
441                                 userLabels.erase(sabund->getLabel());
442                                 
443                                 if (sabund->getMaxRank() > nseqs) {
444                                         for(int i = 1; i <=nseqs; i++) {  sabund->set(i, 0); }
445                                 }else { sabund->clear(); }
446                                 
447                                 if (sabund->getNumBins() > 0) { sabund->print(out); }
448                         }
449                         
450                         if ((m->anyLabelsToProcess(sabund->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
451                                 string saveLabel = sabund->getLabel();
452                                 
453                                 delete sabund;
454                                 sabund = input.getSAbundVector(lastLabel);
455                                 
456                                 m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
457                                 processedLabels.insert(sabund->getLabel());
458                                 userLabels.erase(sabund->getLabel());
459                                 
460                                 if (sabund->getMaxRank() > nseqs) {
461                                         for(int i = 1; i <=nseqs; i++) {  sabund->set(i, 0); }
462                                 }else { sabund->clear(); }
463                                 
464                                 if (sabund->getNumBins() > 0) { sabund->print(out); }
465                                                                 
466                                 //restore real lastlabel to save below
467                                 sabund->setLabel(saveLabel);
468                         }               
469                         
470                         lastLabel = sabund->getLabel();                 
471                         
472                         delete sabund;
473                         sabund = input.getSAbundVector();
474                 }
475                 
476                 if (m->control_pressed) {  out.close(); return 0; }     
477                 
478                 //output error messages about any remaining user labels
479                 set<string>::iterator it;
480                 bool needToRun = false;
481                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
482                         m->mothurOut("Your file does not include the label " + *it); 
483                         if (processedLabels.count(lastLabel) != 1) {
484                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
485                                 needToRun = true;
486                         }else {
487                                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
488                         }
489                 }
490                 
491                 //run last label if you need to
492                 if (needToRun == true)  {
493                         if (sabund != NULL) {   delete sabund;  }
494                         sabund = input.getSAbundVector(lastLabel);
495                         
496                         m->mothurOut(sabund->getLabel()); m->mothurOutEndLine();
497                         
498                         if (sabund->getMaxRank() > nseqs) {
499                                 for(int i = 1; i <=nseqs; i++) {  sabund->set(i, 0); }
500                         }else { sabund->clear(); }
501                         
502                         if (sabund->getNumBins() > 0) { sabund->print(out); }
503                         
504                         delete sabund;
505                 }
506                 
507                 return 0;
508         }
509         catch(exception& e) {
510                 m->errorOut(e, "RemoveRareCommand", "processSabund");
511                 exit(1);
512         }
513 }
514 //**********************************************************************************************************************
515 int RemoveRareCommand::processRabund(){
516         try {
517                 string thisOutputDir = outputDir;
518                 if (outputDir == "") {  thisOutputDir += m->hasPath(rabundfile);  }
519                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(rabundfile)) + "pick" +  m->getExtension(rabundfile);
520                 outputTypes["rabund"].push_back(outputFileName); outputNames.push_back(outputFileName);
521                 
522                 ofstream out;
523                 m->openOutputFile(outputFileName, out);
524                 
525                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
526                 InputData input(rabundfile, "rabund");
527                 RAbundVector* rabund = input.getRAbundVector();
528                 string lastLabel = rabund->getLabel();
529                 set<string> processedLabels;
530                 set<string> userLabels = labels;
531                 
532                 while((rabund != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
533                         
534                         if (m->control_pressed) { delete rabund; out.close(); return 0; }
535                         
536                         if(allLines == 1 || labels.count(rabund->getLabel()) == 1){                     
537                                 
538                                 m->mothurOut(rabund->getLabel()); m->mothurOutEndLine();
539                                 processedLabels.insert(rabund->getLabel());
540                                 userLabels.erase(rabund->getLabel());
541                                 
542                                 RAbundVector newRabund; newRabund.setLabel(rabund->getLabel());
543                                 for (int i = 0; i < rabund->getNumBins(); i++) {
544                                         if (rabund->get(i) > nseqs) {
545                                                 newRabund.push_back(rabund->get(i));
546                                         }
547                                 }
548                                 if (newRabund.getNumBins() > 0) { newRabund.print(out); }
549                         }
550                         
551                         if ((m->anyLabelsToProcess(rabund->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
552                                 string saveLabel = rabund->getLabel();
553                                 
554                                 delete rabund;
555                                 rabund = input.getRAbundVector(lastLabel);
556                                 
557                                 m->mothurOut(rabund->getLabel()); m->mothurOutEndLine();
558                                 processedLabels.insert(rabund->getLabel());
559                                 userLabels.erase(rabund->getLabel());
560                                 
561                                 RAbundVector newRabund; newRabund.setLabel(rabund->getLabel());
562                                 for (int i = 0; i < rabund->getNumBins(); i++) {
563                                         if (rabund->get(i) > nseqs) {
564                                                 newRabund.push_back(rabund->get(i));
565                                         }
566                                 }
567                                 if (newRabund.getNumBins() > 0) { newRabund.print(out); }                               
568                                 
569                                 //restore real lastlabel to save below
570                                 rabund->setLabel(saveLabel);
571                         }               
572                         
573                         lastLabel = rabund->getLabel();                 
574                         
575                         delete rabund;
576                         rabund = input.getRAbundVector();
577                 }
578                 
579                 if (m->control_pressed) {  out.close(); return 0; }     
580                 
581                 //output error messages about any remaining user labels
582                 set<string>::iterator it;
583                 bool needToRun = false;
584                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
585                         m->mothurOut("Your file does not include the label " + *it); 
586                         if (processedLabels.count(lastLabel) != 1) {
587                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
588                                 needToRun = true;
589                         }else {
590                                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
591                         }
592                 }
593                 
594                 //run last label if you need to
595                 if (needToRun == true)  {
596                         if (rabund != NULL) {   delete rabund;  }
597                         rabund = input.getRAbundVector(lastLabel);
598                         
599                         m->mothurOut(rabund->getLabel()); m->mothurOutEndLine();
600                         
601                         RAbundVector newRabund; newRabund.setLabel(rabund->getLabel());
602                         for (int i = 0; i < rabund->getNumBins(); i++) {
603                                 if (rabund->get(i) > nseqs) {
604                                         newRabund.push_back(rabund->get(i));
605                                 }
606                         }
607                         if (newRabund.getNumBins() > 0) { newRabund.print(out); }       
608                         
609                         delete rabund;
610                 }
611                 
612                 return 0;
613         }
614         catch(exception& e) {
615                 m->errorOut(e, "RemoveRareCommand", "processRabund");
616                 exit(1);
617         }
618 }
619 //**********************************************************************************************************************
620 int RemoveRareCommand::processShared(){
621         try {
622                 m->Groups = Groups;
623                 
624                 string thisOutputDir = outputDir;
625                 if (outputDir == "") {  thisOutputDir += m->hasPath(sharedfile);  }
626                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(sharedfile)) + "pick" +  m->getExtension(sharedfile);
627                 outputTypes["shared"].push_back(outputFileName); outputNames.push_back(outputFileName);
628                 
629                 ofstream out;
630                 m->openOutputFile(outputFileName, out);
631                 
632                 //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
633                 InputData input(sharedfile, "sharedfile");
634                 vector<SharedRAbundVector*> lookup = input.getSharedRAbundVectors();
635                 string lastLabel = lookup[0]->getLabel();
636                 set<string> processedLabels;
637                 set<string> userLabels = labels;
638                 
639                 while((lookup[0] != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
640                         
641                         if (m->control_pressed) { for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }  out.close(); return 0; }
642                         
643                         if(allLines == 1 || labels.count(lookup[0]->getLabel()) == 1){                  
644                                 
645                                 m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
646                                 processedLabels.insert(lookup[0]->getLabel());
647                                 userLabels.erase(lookup[0]->getLabel());
648                                 
649                                 if (!m->printedHeaders) { lookup[0]->printHeaders(out); }
650                                 processLookup(lookup, out);
651                         }
652                         
653                         if ((m->anyLabelsToProcess(lookup[0]->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {
654                                 string saveLabel = lookup[0]->getLabel();
655                                 
656                                 for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
657                                 lookup = input.getSharedRAbundVectors(lastLabel);
658                                 
659                                 m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
660                                 processedLabels.insert(lookup[0]->getLabel());
661                                 userLabels.erase(lookup[0]->getLabel());
662                                 
663                                 if (!m->printedHeaders) { lookup[0]->printHeaders(out); }
664                                 processLookup(lookup, out);                     
665                                 
666                                 //restore real lastlabel to save below
667                                 lookup[0]->setLabel(saveLabel);
668                         }               
669                         
670                         lastLabel = lookup[0]->getLabel();                      
671                         
672                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
673                         lookup = input.getSharedRAbundVectors();
674                 }
675                 
676                 if (m->control_pressed) {  out.close(); return 0; }     
677                 
678                 //output error messages about any remaining user labels
679                 set<string>::iterator it;
680                 bool needToRun = false;
681                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  
682                         m->mothurOut("Your file does not include the label " + *it); 
683                         if (processedLabels.count(lastLabel) != 1) {
684                                 m->mothurOut(". I will use " + lastLabel + "."); m->mothurOutEndLine();
685                                 needToRun = true;
686                         }else {
687                                 m->mothurOut(". Please refer to " + lastLabel + "."); m->mothurOutEndLine();
688                         }
689                 }
690                 
691                 //run last label if you need to
692                 if (needToRun == true)  {
693                         for (int i = 0; i < lookup.size(); i++) {  if (lookup[i] != NULL) {     delete lookup[i];       }  }
694                         lookup = input.getSharedRAbundVectors(lastLabel);
695                         
696                         m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
697                         
698                         if (!m->printedHeaders) { lookup[0]->printHeaders(out); }
699                         processLookup(lookup, out);     
700                         
701                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
702                 }
703                 
704                 return 0;
705         }
706         catch(exception& e) {
707                 m->errorOut(e, "RemoveRareCommand", "processSabund");
708                 exit(1);
709         }
710 }
711 //**********************************************************************************************************************
712 int RemoveRareCommand::processLookup(vector<SharedRAbundVector*>& lookup, ofstream& out){
713         try {
714                 
715                 vector<SharedRAbundVector> newRabunds;  newRabunds.resize(lookup.size());
716                 for (int i = 0; i < lookup.size(); i++) {  
717                         newRabunds[i].setGroup(lookup[i]->getGroup());
718                         newRabunds[i].setLabel(lookup[i]->getLabel());
719                 }
720                 
721                 if (byGroup) {
722                         
723                         //for each otu
724                         for (int i = 0; i < lookup[0]->getNumBins(); i++) {
725                                 bool allZero = true;
726                                 
727                                 if (m->control_pressed) { return 0; }
728                                 
729                                 //for each group
730                                 for (int j = 0; j < lookup.size(); j++) {
731                                         
732                                         //are you rare?
733                                         if (lookup[j]->getAbundance(i) > nseqs) {
734                                                 newRabunds[j].push_back(lookup[j]->getAbundance(i), newRabunds[j].getGroup());
735                                                 allZero = false;
736                                         }else {
737                                                 newRabunds[j].push_back(0, newRabunds[j].getGroup());
738                                         }
739                                 }
740                                 
741                                 //eliminates zero otus
742                                 if (allZero) { for (int j = 0; j < newRabunds.size(); j++) {  newRabunds[j].pop_back(); } }
743                         }
744                 }else {
745                         //for each otu
746                         for (int i = 0; i < lookup[0]->getNumBins(); i++) {
747                                 
748                                 if (m->control_pressed) { return 0; }
749                                 
750                                 int totalAbund = 0;
751                                 //get total otu abundance
752                                 for (int j = 0; j < lookup.size(); j++) {
753                                         newRabunds[j].push_back(lookup[j]->getAbundance(i), newRabunds[j].getGroup());
754                                         totalAbund += lookup[j]->getAbundance(i);
755                                 }
756                                 
757                                 //eliminates otus below rare cutoff
758                                 if (totalAbund <= nseqs) { for (int j = 0; j < newRabunds.size(); j++) {  newRabunds[j].pop_back(); } }
759                         }
760                 }
761                 
762                 //do we have any otus above the rare cutoff
763                 if (newRabunds[0].getNumBins() != 0) { 
764                         for (int j = 0; j < newRabunds.size(); j++) { 
765                                 out << newRabunds[j].getLabel() << '\t' << newRabunds[j].getGroup() << '\t';
766                                 newRabunds[j].print(out); 
767                         }
768                 }
769                 
770                 return 0;
771         }
772         catch(exception& e) {
773                 m->errorOut(e, "RemoveRareCommand", "processLookup");
774                 exit(1);
775         }
776 }
777 //**********************************************************************************************************************
778
779
780
781