]> git.donarmstrong.com Git - mothur.git/blob - removegroupscommand.cpp
Merge remote-tracking branch 'mothur/master'
[mothur.git] / removegroupscommand.cpp
1 /*
2  *  removegroupscommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 11/10/10.
6  *  Copyright 2010 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "removegroupscommand.h"
11 #include "sequence.hpp"
12 #include "listvector.hpp"
13 #include "sharedutilities.h"
14 #include "inputdata.h"
15
16 //**********************************************************************************************************************
17 vector<string> RemoveGroupsCommand::setParameters(){    
18         try {
19                 CommandParameter pfasta("fasta", "InputTypes", "", "", "none", "none", "FNGLT",false,false); parameters.push_back(pfasta);
20                 CommandParameter pshared("shared", "InputTypes", "", "", "none", "sharedGroup", "none",false,false); parameters.push_back(pshared);
21                 CommandParameter pname("name", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(pname);
22                 CommandParameter pgroup("group", "InputTypes", "", "", "none", "sharedGroup", "FNGLT",false,false); parameters.push_back(pgroup);
23         CommandParameter pdesign("design", "InputTypes", "", "", "none", "sharedGroup", "FNGLT",false,false); parameters.push_back(pdesign);
24                 CommandParameter plist("list", "InputTypes", "", "", "none", "none", "FNGLT",false,false); parameters.push_back(plist);
25                 CommandParameter ptaxonomy("taxonomy", "InputTypes", "", "", "none", "none", "FNGLT",false,false); parameters.push_back(ptaxonomy);
26                 CommandParameter paccnos("accnos", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(paccnos);
27                 CommandParameter pgroups("groups", "String", "", "", "", "", "",false,false); parameters.push_back(pgroups);
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, "RemoveGroupsCommand", "setParameters");
37                 exit(1);
38         }
39 }
40 //**********************************************************************************************************************
41 string RemoveGroupsCommand::getHelpString(){    
42         try {
43                 string helpString = "";
44                 helpString += "The remove.groups command removes sequences from a specfic group or set of groups from the following file types: fasta, name, group, list, taxonomy, design or sharedfile.\n";
45                 helpString += "It outputs a file containing the sequences NOT in the those specified groups, or with a sharedfile eliminates the groups you selected.\n";
46                 helpString += "The remove.groups command parameters are accnos, fasta, name, group, list, taxonomy, shared, design and groups. The group parameter is required, unless you have a current group file or are using a sharedfile.\n";
47                 helpString += "You must also provide an accnos containing the list of groups to remove or set the groups parameter to the groups you wish to remove.\n";
48                 helpString += "The groups parameter allows you to specify which of the groups in your groupfile you would like removed.  You can separate group names with dashes.\n";
49                 helpString += "The remove.groups command should be in the following format: remove.groups(accnos=yourAccnos, fasta=yourFasta, group=yourGroupFile).\n";
50                 helpString += "Example remove.groups(accnos=amazon.accnos, fasta=amazon.fasta, group=amazon.groups).\n";
51                 helpString += "or remove.groups(groups=pasture, fasta=amazon.fasta, amazon.groups).\n";
52                 helpString += "Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFasta).\n";
53                 return helpString;
54         }
55         catch(exception& e) {
56                 m->errorOut(e, "RemoveGroupsCommand", "getHelpString");
57                 exit(1);
58         }
59 }
60 //**********************************************************************************************************************
61 string RemoveGroupsCommand::getOutputFileNameTag(string type, string inputName=""){     
62         try {
63         string outputFileName = "";
64                 map<string, vector<string> >::iterator it;
65         
66         //is this a type this command creates
67         it = outputTypes.find(type);
68         if (it == outputTypes.end()) {  m->mothurOut("[ERROR]: this command doesn't create a " + type + " output file.\n"); }
69         else {
70             if (type == "fasta")            {   outputFileName =  "pick" + m->getExtension(inputName);   }
71             else if (type == "taxonomy")    {   outputFileName =  "pick" + m->getExtension(inputName);   }
72             else if (type == "name")        {   outputFileName =  "pick" + m->getExtension(inputName);   }
73             else if (type == "group")       {   outputFileName =  "pick" + m->getExtension(inputName);   }
74             else if (type == "list")        {   outputFileName =  "pick" + m->getExtension(inputName);   }
75             else if (type == "shared")      {   outputFileName =  "pick" + m->getExtension(inputName);   }
76             else if (type == "design")      {   outputFileName =  "pick" + m->getExtension(inputName);   }
77             else { m->mothurOut("[ERROR]: No definition for type " + type + " output file tag.\n"); m->control_pressed = true;  }
78         }
79         return outputFileName;
80         }
81         catch(exception& e) {
82                 m->errorOut(e, "RemoveGroupsCommand", "getOutputFileNameTag");
83                 exit(1);
84         }
85 }
86 //**********************************************************************************************************************
87 RemoveGroupsCommand::RemoveGroupsCommand(){     
88         try {
89                 abort = true; calledHelp = true; 
90                 setParameters();
91                 vector<string> tempOutNames;
92                 outputTypes["fasta"] = tempOutNames;
93                 outputTypes["taxonomy"] = tempOutNames;
94                 outputTypes["name"] = tempOutNames;
95                 outputTypes["group"] = tempOutNames;
96                 outputTypes["list"] = tempOutNames;
97                 outputTypes["shared"] = tempOutNames;
98         outputTypes["design"] = tempOutNames;
99         }
100         catch(exception& e) {
101                 m->errorOut(e, "RemoveGroupsCommand", "RemoveGroupsCommand");
102                 exit(1);
103         }
104 }
105 //**********************************************************************************************************************
106 RemoveGroupsCommand::RemoveGroupsCommand(string option)  {
107         try {
108                 abort = false; calledHelp = false;   
109                 
110                 //allow user to run help
111                 if(option == "help") { help(); abort = true; calledHelp = true; }
112                 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
113                 
114                 else {
115                         vector<string> myArray = setParameters();
116                         
117                         OptionParser parser(option);
118                         map<string,string> parameters = parser.getParameters();
119                         
120                         ValidParameters validParameter;
121                         map<string,string>::iterator it;
122                         
123                         //check to make sure all parameters are valid for command
124                         for (it = parameters.begin(); it != parameters.end(); it++) { 
125                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
126                         }
127                         
128                         //initialize outputTypes
129                         vector<string> tempOutNames;
130                         outputTypes["fasta"] = tempOutNames;
131                         outputTypes["taxonomy"] = tempOutNames;
132                         outputTypes["name"] = tempOutNames;
133                         outputTypes["group"] = tempOutNames;
134                         outputTypes["list"] = tempOutNames;
135                         outputTypes["shared"] = tempOutNames;
136             outputTypes["design"] = tempOutNames;
137                         
138                         
139                         //if the user changes the output directory command factory will send this info to us in the output parameter 
140                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = "";         }
141                         
142                         //if the user changes the input directory command factory will send this info to us in the output parameter 
143                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
144                         if (inputDir == "not found"){   inputDir = "";          }
145                         else {
146                                 string path;
147                                 it = parameters.find("fasta");
148                                 //user has given a template file
149                                 if(it != parameters.end()){ 
150                                         path = m->hasPath(it->second);
151                                         //if the user has not given a path then, add inputdir. else leave path alone.
152                                         if (path == "") {       parameters["fasta"] = inputDir + it->second;            }
153                                 }
154                                 
155                                 it = parameters.find("accnos");
156                                 //user has given a template file
157                                 if(it != parameters.end()){ 
158                                         path = m->hasPath(it->second);
159                                         //if the user has not given a path then, add inputdir. else leave path alone.
160                                         if (path == "") {       parameters["accnos"] = inputDir + it->second;           }
161                                 }
162                                 
163                                 it = parameters.find("list");
164                                 //user has given a template file
165                                 if(it != parameters.end()){ 
166                                         path = m->hasPath(it->second);
167                                         //if the user has not given a path then, add inputdir. else leave path alone.
168                                         if (path == "") {       parameters["list"] = inputDir + it->second;             }
169                                 }
170                                 
171                                 it = parameters.find("name");
172                                 //user has given a template file
173                                 if(it != parameters.end()){ 
174                                         path = m->hasPath(it->second);
175                                         //if the user has not given a path then, add inputdir. else leave path alone.
176                                         if (path == "") {       parameters["name"] = inputDir + it->second;             }
177                                 }
178                                 
179                                 it = parameters.find("group");
180                                 //user has given a template file
181                                 if(it != parameters.end()){ 
182                                         path = m->hasPath(it->second);
183                                         //if the user has not given a path then, add inputdir. else leave path alone.
184                                         if (path == "") {       parameters["group"] = inputDir + it->second;            }
185                                 }
186                                 
187                                 it = parameters.find("taxonomy");
188                                 //user has given a template file
189                                 if(it != parameters.end()){ 
190                                         path = m->hasPath(it->second);
191                                         //if the user has not given a path then, add inputdir. else leave path alone.
192                                         if (path == "") {       parameters["taxonomy"] = inputDir + it->second;         }
193                                 }
194                                 
195                                 it = parameters.find("shared");
196                                 //user has given a template file
197                                 if(it != parameters.end()){ 
198                                         path = m->hasPath(it->second);
199                                         //if the user has not given a path then, add inputdir. else leave path alone.
200                                         if (path == "") {       parameters["shared"] = inputDir + it->second;           }
201                                 }
202                 
203                 it = parameters.find("design");
204                                 //user has given a template file
205                                 if(it != parameters.end()){ 
206                                         path = m->hasPath(it->second);
207                                         //if the user has not given a path then, add inputdir. else leave path alone.
208                                         if (path == "") {       parameters["design"] = inputDir + it->second;           }
209                                 }
210                         }
211                         
212                         
213                         //check for required parameters
214                         accnosfile = validParameter.validFile(parameters, "accnos", true);
215                         if (accnosfile == "not open") { accnosfile = ""; abort = true; }
216                         else if (accnosfile == "not found") {  accnosfile = ""; }       
217                         else { m->setAccnosFile(accnosfile); }
218                         
219                         fastafile = validParameter.validFile(parameters, "fasta", true);
220                         if (fastafile == "not open") { fastafile = ""; abort = true; }
221                         else if (fastafile == "not found") {  fastafile = "";  }        
222                         else { m->setFastaFile(fastafile); }
223                         
224                         namefile = validParameter.validFile(parameters, "name", true);
225                         if (namefile == "not open") { namefile = ""; abort = true; }
226                         else if (namefile == "not found") {  namefile = "";  }  
227                         else { m->setNameFile(namefile); }
228                         
229                         groupfile = validParameter.validFile(parameters, "group", true);
230                         if (groupfile == "not open") { groupfile = "";  abort = true; }
231                         else if (groupfile == "not found") {    groupfile = "";         }
232                         else { m->setGroupFile(groupfile); }    
233                         
234                         listfile = validParameter.validFile(parameters, "list", true);
235                         if (listfile == "not open") { listfile = ""; abort = true; }
236                         else if (listfile == "not found") {  listfile = "";  }
237                         else { m->setListFile(listfile); }
238                         
239                         taxfile = validParameter.validFile(parameters, "taxonomy", true);
240                         if (taxfile == "not open") { taxfile = ""; abort = true; }
241                         else if (taxfile == "not found") {  taxfile = "";  }
242                         else { m->setTaxonomyFile(taxfile); }
243             
244             designfile = validParameter.validFile(parameters, "design", true);
245                         if (designfile == "not open") { designfile = ""; abort = true; }
246                         else if (designfile == "not found") {  designfile = "";  }
247                         else { m->setDesignFile(designfile); }
248                         
249                         groups = validParameter.validFile(parameters, "groups", false);                 
250                         if (groups == "not found") { groups = ""; }
251                         else { 
252                                 m->splitAtDash(groups, Groups);
253                                 m->setGroups(Groups);
254                         }
255                         
256                         sharedfile = validParameter.validFile(parameters, "shared", true);
257                         if (sharedfile == "not open") { sharedfile = ""; abort = true; }
258                         else if (sharedfile == "not found") {  sharedfile = "";  }
259                         else { m->setSharedFile(sharedfile); }
260                         
261                         groupfile = validParameter.validFile(parameters, "group", true);
262                         if (groupfile == "not open") { groupfile = ""; abort = true; }
263                         else if (groupfile == "not found") {    groupfile = ""; }
264                         else { m->setGroupFile(groupfile); }    
265                         
266                         if ((sharedfile == "") && (groupfile == "") && (designfile == "")) { 
267                                 //is there are current file available for any of these?
268                                 if ((namefile != "") || (fastafile != "") || (listfile != "") || (taxfile != "")) {
269                                         //give priority to group, then shared
270                                         groupfile = m->getGroupFile(); 
271                                         if (groupfile != "") {  m->mothurOut("Using " + groupfile + " as input file for the group parameter."); m->mothurOutEndLine(); }
272                                         else { 
273                                                 sharedfile = m->getSharedFile(); 
274                                                 if (sharedfile != "") { m->mothurOut("Using " + sharedfile + " as input file for the shared parameter."); m->mothurOutEndLine(); }
275                                                 else { 
276                                                         m->mothurOut("You have no current groupfile or sharedfile and one is required."); m->mothurOutEndLine(); abort = true;
277                                                 }
278                                         }
279                                 }else {
280                                         //give priority to shared, then group
281                                         sharedfile = m->getSharedFile(); 
282                                         if (sharedfile != "") {  m->mothurOut("Using " + sharedfile + " as input file for the shared parameter."); m->mothurOutEndLine(); }
283                                         else { 
284                                                 groupfile = m->getGroupFile(); 
285                                                 if (groupfile != "") { m->mothurOut("Using " + groupfile + " as input file for the group parameter."); m->mothurOutEndLine(); }
286                                                 else { 
287                                                         designfile = m->getDesignFile(); 
288                             if (designfile != "") { m->mothurOut("Using " + designfile + " as input file for the design parameter."); m->mothurOutEndLine(); }
289                             else { 
290                                 m->mothurOut("You have no current groupfile or sharedfile or designfile and one is required."); m->mothurOutEndLine(); abort = true;
291                             }
292                                                 }
293                                         }
294                                 }
295                         }
296                         
297                         if ((accnosfile == "") && (Groups.size() == 0)) { m->mothurOut("You must provide an accnos file containing group names or specify groups using the groups parameter."); m->mothurOutEndLine(); abort = true; }
298                         
299                         if ((fastafile == "") && (namefile == "") && (groupfile == "")  && (sharedfile == "") && (designfile == "") && (listfile == "") && (taxfile == ""))  { m->mothurOut("You must provide at least one of the following: fasta, name, taxonomy, group, shared, design or list."); m->mothurOutEndLine(); abort = true; }
300                         if ((groupfile == "") && ((namefile != "") || (fastafile != "") || (listfile != "") || (taxfile != "")))  { m->mothurOut("If using a fasta, name, taxonomy, group or list, then you must provide a group file."); m->mothurOutEndLine(); abort = true; }
301                         
302                         if ((namefile == "") && ((fastafile != "") || (taxfile != ""))){
303                                 vector<string> files; files.push_back(fastafile); files.push_back(taxfile);
304                                 parser.getNameFile(files);
305                         }
306                 
307                 }
308                 
309         }
310         catch(exception& e) {
311                 m->errorOut(e, "RemoveGroupsCommand", "RemoveGroupsCommand");
312                 exit(1);
313         }
314 }
315 //**********************************************************************************************************************
316
317 int RemoveGroupsCommand::execute(){
318         try {
319                 
320                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
321                 
322                 //get groups you want to remove
323                 if (accnosfile != "") { m->readAccnos(accnosfile, Groups); m->setGroups(Groups);  }
324                 
325                 if (groupfile != "") {
326                         groupMap = new GroupMap(groupfile);
327                         groupMap->readMap();
328                         
329                         //make sure groups are valid
330                         //takes care of user setting groupNames that are invalid or setting groups=all
331                         SharedUtil* util = new SharedUtil();
332                         vector<string> namesGroups = groupMap->getNamesOfGroups();
333                         util->setGroups(Groups, namesGroups);
334                         delete util;
335                         
336                         //fill names with names of sequences that are from the groups we want to remove 
337                         fillNames();
338                         
339                         delete groupMap;
340                 }
341                                 
342                 if (m->control_pressed) { return 0; }
343                 
344                 //read through the correct file and output lines you want to keep
345                 if (namefile != "")                     {               readName();             }
346                 if (fastafile != "")            {               readFasta();    }
347                 if (groupfile != "")            {               readGroup();    }
348                 if (listfile != "")                     {               readList();             }
349                 if (taxfile != "")                      {               readTax();              }
350                 if (sharedfile != "")           {               readShared();   }
351         if (designfile != "")           {               readDesign();   }
352                 
353                 if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) {        m->mothurRemove(outputNames[i]); } return 0; }
354                                 
355                 if (outputNames.size() != 0) {
356                         m->mothurOutEndLine();
357                         m->mothurOut("Output File names: "); m->mothurOutEndLine();
358                         for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
359                         m->mothurOutEndLine();
360                         
361                         //set fasta file as new current fastafile
362                         string current = "";
363                         itTypes = outputTypes.find("fasta");
364                         if (itTypes != outputTypes.end()) {
365                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setFastaFile(current); }
366                         }
367                         
368                         itTypes = outputTypes.find("name");
369                         if (itTypes != outputTypes.end()) {
370                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setNameFile(current); }
371                         }
372                         
373                         itTypes = outputTypes.find("group");
374                         if (itTypes != outputTypes.end()) {
375                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setGroupFile(current); }
376                         }
377                         
378                         itTypes = outputTypes.find("list");
379                         if (itTypes != outputTypes.end()) {
380                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setListFile(current); }
381                         }
382                         
383                         itTypes = outputTypes.find("taxonomy");
384                         if (itTypes != outputTypes.end()) {
385                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setTaxonomyFile(current); }
386                         }
387                         
388                         itTypes = outputTypes.find("shared");
389                         if (itTypes != outputTypes.end()) {
390                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setSharedFile(current); }
391                         }
392             
393             itTypes = outputTypes.find("design");
394                         if (itTypes != outputTypes.end()) {
395                                 if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setDesignFile(current); }
396                         }
397                 }
398                 
399                 return 0;               
400         }
401         
402         catch(exception& e) {
403                 m->errorOut(e, "RemoveGroupsCommand", "execute");
404                 exit(1);
405         }
406 }
407
408 //**********************************************************************************************************************
409 int RemoveGroupsCommand::readFasta(){
410         try {
411                 string thisOutputDir = outputDir;
412                 if (outputDir == "") {  thisOutputDir += m->hasPath(fastafile);  }
413                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(fastafile)) + getOutputFileNameTag("fasta", fastafile);
414                 
415                 ofstream out;
416                 m->openOutputFile(outputFileName, out);
417                 
418                 ifstream in;
419                 m->openInputFile(fastafile, in);
420                 string name;
421                 
422                 bool wroteSomething = false;
423                 int removedCount = 0;
424                 
425                 while(!in.eof()){
426                         if (m->control_pressed) { in.close();  out.close();  m->mothurRemove(outputFileName);  return 0; }
427                         
428                         Sequence currSeq(in);
429                         name = currSeq.getName();
430                         
431                         if (name != "") {
432                                 //if this name is in the accnos file
433                                 if (names.count(name) == 0) {
434                                         wroteSomething = true;
435                                         currSeq.printSequence(out); 
436                                 }else { 
437                                         //if you are not in the accnos file check if you are a name that needs to be changed
438                                         map<string, string>::iterator it = uniqueToRedundant.find(name);
439                                         if (it != uniqueToRedundant.end()) {
440                                                 wroteSomething = true;
441                                                 currSeq.setName(it->second);
442                                                 currSeq.printSequence(out);
443                                         }else { removedCount++; }
444                                 }
445                         }
446                         m->gobble(in);
447                 }
448                 in.close();     
449                 out.close();
450                 
451                 if (wroteSomething == false) {  m->mothurOut("Your file contains only sequences from the groups you wish to remove."); m->mothurOutEndLine();  }
452                 outputTypes["fasta"].push_back(outputFileName);  outputNames.push_back(outputFileName);
453                 
454                 m->mothurOut("Removed " + toString(removedCount) + " sequences from your fasta file."); m->mothurOutEndLine();
455                 
456                 return 0;
457                 
458         }
459         catch(exception& e) {
460                 m->errorOut(e, "RemoveGroupsCommand", "readFasta");
461                 exit(1);
462         }
463 }
464 //**********************************************************************************************************************
465 int RemoveGroupsCommand::readShared(){
466         try {
467                 string thisOutputDir = outputDir;
468                 if (outputDir == "") {  thisOutputDir += m->hasPath(sharedfile);  }
469                 
470                 //get group names from sharedfile so we can set Groups to the groupNames we want to keep
471                 //that way we can take advantage of the reads in inputdata and sharedRabundVector
472                 InputData* tempInput = new InputData(sharedfile, "sharedfile");
473                 vector<SharedRAbundVector*> lookup = tempInput->getSharedRAbundVectors();
474         
475                 //save m->Groups
476                 vector<string> allGroupsNames = m->getAllGroups();
477                 vector<string> mothurOutGroups = m->getGroups();
478                 
479                 vector<string> groupsToKeep;
480                 for (int i = 0; i < allGroupsNames.size(); i++) {
481                         if (!m->inUsersGroups(allGroupsNames[i], m->getGroups())) {
482                                 groupsToKeep.push_back(allGroupsNames[i]);
483                         }
484                 }
485                 
486                 if (allGroupsNames.size() == groupsToKeep.size()) { m->mothurOut("Your file does not contain any groups you wish to remove."); m->mothurOutEndLine(); m->setGroups(mothurOutGroups); delete tempInput; for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }  return 0; }
487                 
488                 //reset read 
489                 for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
490                 delete tempInput;
491                 m->setGroups(groupsToKeep);
492                 m->clearAllGroups();
493                 m->saveNextLabel = "";
494                 m->printedHeaders = false;
495                 m->currentBinLabels.clear();
496                 m->binLabelsInFile.clear();
497                 
498                 InputData input(sharedfile, "sharedfile");
499                 lookup = input.getSharedRAbundVectors();
500
501                 bool wroteSomething = false;
502                 
503                 while(lookup[0] != NULL) {
504                         
505                         string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(sharedfile)) + lookup[0]->getLabel() + "." + getOutputFileNameTag("shared", sharedfile);
506                         ofstream out;
507                         m->openOutputFile(outputFileName, out);
508                         outputTypes["shared"].push_back(outputFileName);  outputNames.push_back(outputFileName);
509                         
510                         if (m->control_pressed) { out.close();  m->mothurRemove(outputFileName);  for (int i = 0; i < lookup.size(); i++) { delete lookup[i]; } return 0; }
511                         
512                         lookup[0]->printHeaders(out); 
513                         
514                         for (int i = 0; i < lookup.size(); i++) {
515                                 out << lookup[i]->getLabel() << '\t' << lookup[i]->getGroup() << '\t';
516                                 lookup[i]->print(out);
517                                 wroteSomething = true;
518                                 
519                         }                       
520                         
521                         //get next line to process
522                         //prevent memory leak
523                         for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  } 
524                         lookup = input.getSharedRAbundVectors();
525                         
526                         out.close();
527                 }
528                 
529                 
530                 m->setGroups(mothurOutGroups);
531                 
532                 if (wroteSomething == false) {  m->mothurOut("Your file contains only the groups you wish to remove."); m->mothurOutEndLine();  }
533                 
534                 string groupsString = "";
535                 for (int i = 0; i < Groups.size()-1; i++) {     groupsString += Groups[i] + ", "; }
536                 groupsString += Groups[Groups.size()-1];
537                 
538                 m->mothurOut("Removed groups: " + groupsString + " from your shared file."); m->mothurOutEndLine();
539                 
540                 return 0;
541                 
542         }
543         catch(exception& e) {
544                 m->errorOut(e, "RemoveGroupsCommand", "readShared");
545                 exit(1);
546         }
547 }
548 //**********************************************************************************************************************
549 int RemoveGroupsCommand::readList(){
550         try {
551                 string thisOutputDir = outputDir;
552                 if (outputDir == "") {  thisOutputDir += m->hasPath(listfile);  }
553                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(listfile)) + getOutputFileNameTag("list", listfile);
554                 
555                 ofstream out;
556                 m->openOutputFile(outputFileName, out);
557                 
558                 ifstream in;
559                 m->openInputFile(listfile, in);
560                 
561                 bool wroteSomething = false;
562                 int removedCount = 0;
563                 
564                 while(!in.eof()){
565                         
566                         removedCount = 0;
567                         
568                         //read in list vector
569                         ListVector list(in);
570                         
571                         //make a new list vector
572                         ListVector newList;
573                         newList.setLabel(list.getLabel());
574                         
575                         //for each bin
576                         for (int i = 0; i < list.getNumBins(); i++) {
577                                 if (m->control_pressed) { in.close();  out.close();  m->mothurRemove(outputFileName);  return 0; }
578                                 
579                                 //parse out names that are in accnos file
580                                 string binnames = list.get(i);
581                                 
582                                 string newNames = "";
583                                 while (binnames.find_first_of(',') != -1) { 
584                                         string name = binnames.substr(0,binnames.find_first_of(','));
585                                         binnames = binnames.substr(binnames.find_first_of(',')+1, binnames.length());
586                                         
587                                         //if that name is in the .accnos file, add it
588                                         if (names.count(name) == 0) {  newNames += name + ",";  }
589                                         else {
590                                                 //if you are not in the accnos file check if you are a name that needs to be changed
591                                                 map<string, string>::iterator it = uniqueToRedundant.find(name);
592                                                 if (it != uniqueToRedundant.end()) {
593                                                         newNames += it->second + ",";
594                                                 }else { removedCount++; }
595                                         }
596                                 }
597                                 
598                                 //get last name
599                                 if (names.count(binnames) == 0) {  newNames += binnames + ",";  }
600                                 else { //if you are not in the accnos file check if you are a name that needs to be changed
601                                         map<string, string>::iterator it = uniqueToRedundant.find(binnames);
602                                         if (it != uniqueToRedundant.end()) {
603                                                 newNames += it->second + ",";
604                                         }else { removedCount++; }
605                                 }
606                                 
607                                 //if there are names in this bin add to new list
608                                 if (newNames != "") {  
609                                         newNames = newNames.substr(0, newNames.length()-1); //rip off extra comma
610                                         newList.push_back(newNames);    
611                                 }
612                         }
613                         
614                         //print new listvector
615                         if (newList.getNumBins() != 0) {
616                                 wroteSomething = true;
617                                 newList.print(out);
618                         }
619                         
620                         m->gobble(in);
621                 }
622                 in.close();     
623                 out.close();
624                 
625                 if (wroteSomething == false) {  m->mothurOut("Your file contains only sequences from the groups you wish to remove."); m->mothurOutEndLine();  }
626                 outputTypes["list"].push_back(outputFileName); outputNames.push_back(outputFileName);
627                 
628                 m->mothurOut("Removed " + toString(removedCount) + " sequences from your list file."); m->mothurOutEndLine();
629                 
630                 return 0;
631                 
632         }
633         catch(exception& e) {
634                 m->errorOut(e, "RemoveGroupsCommand", "readList");
635                 exit(1);
636         }
637 }
638 //**********************************************************************************************************************
639 int RemoveGroupsCommand::readName(){
640         try {
641                 string thisOutputDir = outputDir;
642                 if (outputDir == "") {  thisOutputDir += m->hasPath(namefile);  }
643                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(namefile)) + getOutputFileNameTag("name", namefile);            
644                 ofstream out;
645                 m->openOutputFile(outputFileName, out);
646                 
647                 ifstream in;
648                 m->openInputFile(namefile, in);
649                 string name, firstCol, secondCol;
650                 
651                 bool wroteSomething = false;
652                 int removedCount = 0;
653                 
654                 while(!in.eof()){
655                         if (m->control_pressed) { in.close();  out.close();  m->mothurRemove(outputFileName);  return 0; }
656                         
657                         in >> firstCol;         m->gobble(in);          
658                         in >> secondCol;                        
659                         
660                         vector<string> parsedNames;
661                         m->splitAtComma(secondCol, parsedNames);
662                                                 
663                         vector<string> validSecond;  validSecond.clear();
664                         for (int i = 0; i < parsedNames.size(); i++) {
665                                 if (names.count(parsedNames[i]) == 0) {
666                                         validSecond.push_back(parsedNames[i]);
667                                 }
668                         }
669                         
670                         removedCount += parsedNames.size()-validSecond.size();
671                         
672                         //if the name in the first column is in the set then print it and any other names in second column also in set
673                         if (names.count(firstCol) == 0) {
674                                 
675                                 wroteSomething = true;
676                                 
677                                 out << firstCol << '\t';
678                                 
679                                 //you know you have at least one valid second since first column is valid
680                                 for (int i = 0; i < validSecond.size()-1; i++) {  out << validSecond[i] << ',';  }
681                                 out << validSecond[validSecond.size()-1] << endl;
682                                 
683                                 //make first name in set you come to first column and then add the remaining names to second column
684                         }else {
685                                 
686                                 //you want part of this row
687                                 if (validSecond.size() != 0) {
688                                         
689                                         wroteSomething = true;
690                                         
691                                         out << validSecond[0] << '\t';
692                                         
693                                         //you know you have at least one valid second since first column is valid
694                                         for (int i = 0; i < validSecond.size()-1; i++) {  out << validSecond[i] << ',';  }
695                                         out << validSecond[validSecond.size()-1] << endl;
696                                         uniqueToRedundant[firstCol] = validSecond[0];
697                                 }
698                         }
699                         
700                         m->gobble(in);
701                 }
702                 in.close();
703                 out.close();
704                 
705                 if (wroteSomething == false) {  m->mothurOut("Your file contains only sequences from the groups you wish to remove."); m->mothurOutEndLine();  }
706                 outputTypes["name"].push_back(outputFileName); outputNames.push_back(outputFileName);
707                 
708                 m->mothurOut("Removed " + toString(removedCount) + " sequences from your name file."); m->mothurOutEndLine();
709                 
710                 return 0;
711         }
712         catch(exception& e) {
713                 m->errorOut(e, "RemoveGroupsCommand", "readName");
714                 exit(1);
715         }
716 }
717
718 //**********************************************************************************************************************
719 int RemoveGroupsCommand::readGroup(){
720         try {
721                 string thisOutputDir = outputDir;
722                 if (outputDir == "") {  thisOutputDir += m->hasPath(groupfile);  }
723                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(groupfile)) + getOutputFileNameTag("group", groupfile);         
724                 ofstream out;
725                 m->openOutputFile(outputFileName, out);
726                 
727                 ifstream in;
728                 m->openInputFile(groupfile, in);
729                 string name, group;
730                 
731                 bool wroteSomething = false;
732                 int removedCount = 0;
733                 
734                 while(!in.eof()){
735                         if (m->control_pressed) { in.close();  out.close();  m->mothurRemove(outputFileName);  return 0; }
736                         
737                         in >> name;                             //read from first column
738                         in >> group;                    //read from second column
739                         
740                         //if this name is in the accnos file
741                         if (names.count(name) == 0) {
742                                 wroteSomething = true;
743                                 out << name << '\t' << group << endl;
744                         }else {  removedCount++;  }
745                         
746                         m->gobble(in);
747                 }
748                 in.close();
749                 out.close();
750                 
751                 if (wroteSomething == false) {  m->mothurOut("Your file contains only sequences from the groups you wish to remove."); m->mothurOutEndLine();  }
752                 outputTypes["group"].push_back(outputFileName); outputNames.push_back(outputFileName);
753                 
754                 m->mothurOut("Removed " + toString(removedCount) + " sequences from your group file."); m->mothurOutEndLine();
755
756                 
757                 return 0;
758         }
759         catch(exception& e) {
760                 m->errorOut(e, "RemoveGroupsCommand", "readGroup");
761                 exit(1);
762         }
763 }
764 //**********************************************************************************************************************
765 int RemoveGroupsCommand::readDesign(){
766         try {
767                 string thisOutputDir = outputDir;
768                 if (outputDir == "") {  thisOutputDir += m->hasPath(designfile);  }
769                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(designfile)) + getOutputFileNameTag("design", designfile);
770                 
771                 ofstream out;
772                 m->openOutputFile(outputFileName, out);
773                 
774                 ifstream in;
775                 m->openInputFile(designfile, in);
776                 string name, group;
777                 
778                 bool wroteSomething = false;
779                 int removedCount = 0;
780                 
781                 while(!in.eof()){
782                         if (m->control_pressed) { in.close();  out.close();  m->mothurRemove(outputFileName);  return 0; }
783                         
784                         in >> name;                             //read from first column
785                         in >> group;                    //read from second column
786                         
787                         //if this name is in the accnos file
788                         if (!(m->inUsersGroups(name, Groups))) {
789                                 wroteSomething = true;
790                                 out << name << '\t' << group << endl;
791                         }else {  removedCount++;  }
792                         
793                         m->gobble(in);
794                 }
795                 in.close();
796                 out.close();
797                 
798                 if (wroteSomething == false) {  m->mothurOut("Your file contains only groups from the groups you wish to remove."); m->mothurOutEndLine();  }
799                 outputTypes["design"].push_back(outputFileName); outputNames.push_back(outputFileName);
800                 
801                 m->mothurOut("Removed " + toString(removedCount) + " groups from your design file."); m->mothurOutEndLine();
802         
803                 
804                 return 0;
805         }
806         catch(exception& e) {
807                 m->errorOut(e, "RemoveGroupsCommand", "readDesign");
808                 exit(1);
809         }
810 }
811
812 //**********************************************************************************************************************
813 int RemoveGroupsCommand::readTax(){
814         try {
815                 string thisOutputDir = outputDir;
816                 if (outputDir == "") {  thisOutputDir += m->hasPath(taxfile);  }
817                 string outputFileName = thisOutputDir + m->getRootName(m->getSimpleName(taxfile)) + getOutputFileNameTag("taxonomy", taxfile);
818                 ofstream out;
819                 m->openOutputFile(outputFileName, out);
820                 
821                 ifstream in;
822                 m->openInputFile(taxfile, in);
823                 string name, tax;
824                 
825                 bool wroteSomething = false;
826                 int removedCount = 0;
827                 
828                 while(!in.eof()){
829                         if (m->control_pressed) { in.close();  out.close();  m->mothurRemove(outputFileName);  return 0; }
830                         
831                         in >> name;                             //read from first column
832                         in >> tax;                      //read from second column
833                         
834                         //if this name is in the accnos file
835                         if (names.count(name) == 0) {
836                                 wroteSomething = true;
837                                 out << name << '\t' << tax << endl;
838                         }else {  //if you are not in the accnos file check if you are a name that needs to be changed
839                                 map<string, string>::iterator it = uniqueToRedundant.find(name);
840                                 if (it != uniqueToRedundant.end()) {
841                                         wroteSomething = true;
842                                         out << it->second << '\t' << tax << endl;
843                                 }else { removedCount++; }  }
844                         
845                         m->gobble(in);
846                 }
847                 in.close();
848                 out.close();
849                 
850                 if (wroteSomething == false) {  m->mothurOut("Your file contains only sequences from the groups you wish to remove."); m->mothurOutEndLine();  }
851                 outputTypes["taxonomy"].push_back(outputFileName); outputNames.push_back(outputFileName);
852                 
853                 m->mothurOut("Removed " + toString(removedCount) + " sequences from your taxonomy file."); m->mothurOutEndLine();
854                 
855                 return 0;
856         }
857         catch(exception& e) {
858                 m->errorOut(e, "RemoveGroupsCommand", "readTax");
859                 exit(1);
860         }
861 }
862 //**********************************************************************************************************************
863 int RemoveGroupsCommand::fillNames(){
864         try {
865                 vector<string> seqs = groupMap->getNamesSeqs();
866                 
867                 for (int i = 0; i < seqs.size(); i++) {
868                         
869                         if (m->control_pressed) { return 0; }
870                         
871                         string group = groupMap->getGroup(seqs[i]);
872                         
873                         if (m->inUsersGroups(group, Groups)) {
874                                 names.insert(seqs[i]);
875                         }
876                 }
877                 
878                 return 0;
879         }
880         catch(exception& e) {
881                 m->errorOut(e, "RemoveGroupsCommand", "fillNames");
882                 exit(1);
883         }
884 }
885
886 //**********************************************************************************************************************
887
888
889