1 /*
2 * getsharedotucommand.cpp
3 * Mothur
4 *
5 * Created by westcott on 9/22/09.
6 * Copyright 2009 Schloss Lab. All rights reserved.
7 *
8 */
9
10 #include "getsharedotucommand.h"
11
12
13 //**********************************************************************************************************************
setParameters()14 vector<string> GetSharedOTUCommand::setParameters(){
15 try {
16 CommandParameter pfasta("fasta", "InputTypes", "", "", "sharedFasta", "none", "none","fasta",false,false); parameters.push_back(pfasta);
17 CommandParameter pgroup("group", "InputTypes", "", "", "none", "GroupCount", "groupList","",false,false,true); parameters.push_back(pgroup);
18 CommandParameter pcount("count", "InputTypes", "", "", "none", "GroupCount", "none","",false,false); parameters.push_back(pcount);
19 CommandParameter plist("list", "InputTypes", "", "", "sharedList", "sharedList", "groupList","sharedseq",false,false,true); parameters.push_back(plist);
20 CommandParameter pshared("shared", "InputTypes", "", "", "sharedList-sharedFasta", "sharedList", "none","sharedseq",false,false,true); parameters.push_back(pshared);
21 CommandParameter poutput("output", "Multiple", "accnos-default", "default", "", "", "","",false,false); parameters.push_back(poutput);
22 CommandParameter plabel("label", "String", "", "", "", "", "","",false,false); parameters.push_back(plabel);
23 CommandParameter puniquegroups("uniquegroups", "String", "", "", "", "", "","",false,false,true); parameters.push_back(puniquegroups);
24 CommandParameter psharedgroups("sharedgroups", "String", "", "", "", "", "","",false,false,true); parameters.push_back(psharedgroups);
25 CommandParameter pseed("seed", "Number", "", "0", "", "", "","",false,false); parameters.push_back(pseed);
26 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
27 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
28
29 abort = false; calledHelp = false;
30 userGroups = ""; unique = true; allLines = true;
31
32 vector<string> tempOutNames;
33 outputTypes["fasta"] = tempOutNames;
34 outputTypes["accnos"] = tempOutNames;
35 outputTypes["sharedseqs"] = tempOutNames;
36
37 vector<string> myArray;
38 for (int i = 0; i < parameters.size(); i++) { myArray.push_back(parameters[i].name); }
39 return myArray;
40 }
41 catch(exception& e) {
42 m->errorOut(e, "GetSharedOTUCommand", "setParameters");
43 exit(1);
44 }
45 }
46 //**********************************************************************************************************************
getHelpString()47 string GetSharedOTUCommand::getHelpString(){
48 try {
49 string helpString = "";
50 helpString += "The get.sharedseqs command parameters are list, group, shared, label, uniquegroups, sharedgroups, output and fasta. The list and group or shared parameters are required, unless you have valid current files.\n";
51 helpString += "The label parameter allows you to select what distance levels you would like output files for, and are separated by dashes.\n";
52 helpString += "The uniquegroups and sharedgroups parameters allow you to select groups you would like to know the shared info for, and are separated by dashes.\n";
53 helpString += "If you enter your groups under the uniquegroups parameter mothur will return the otus that contain ONLY sequences from those groups.\n";
54 helpString += "If you enter your groups under the sharedgroups parameter mothur will return the otus that contain sequences from those groups and may also contain sequences from other groups.\n";
55 helpString += "If you do not enter any groups then the get.sharedseqs command will return sequences that are unique to all groups in your group or shared file.\n";
56 helpString += "The fasta parameter allows you to input a fasta file and outputs a fasta file for each distance level containing only the sequences that are in OTUs shared by the groups specified. It can only be used with a list and group file not the shared file input.\n";
57 helpString += "The count parameter allows you to provide a count file containing the group info for the list file.\n";
58 helpString += "The output parameter allows you to output the list of names without the group and bin number added. \n";
59 helpString += "With this option you can use the names file as an input in get.seqs and remove.seqs commands. To do this enter output=accnos. \n";
60 helpString += "The get.sharedseqs command outputs a .names file for each distance level containing a list of sequences in the OTUs shared by the groups specified.\n";
61 helpString += "The get.sharedseqs command should be in the following format: get.sharedseqs(list=yourListFile, group=yourGroupFile, label=yourLabels, uniquegroups=yourGroups, fasta=yourFastafile, output=yourOutput).\n";
62 helpString += "Example get.sharedseqs(list=amazon.fn.list, label=unique-0.01, group=amazon.groups, uniquegroups=forest-pasture, fasta=amazon.fasta, output=accnos).\n";
63 helpString += "The output to the screen is the distance and the number of otus at that distance for the groups you specified.\n";
64 helpString += "The default value for label is all labels in your inputfile. The default for groups is all groups in your file.\n";
65 return helpString;
66 }
67 catch(exception& e) {
68 m->errorOut(e, "GetSharedOTUCommand", "getHelpString");
69 exit(1);
70 }
71 }
72 //**********************************************************************************************************************
getOutputPattern(string type)73 string GetSharedOTUCommand::getOutputPattern(string type) {
74 try {
75 string pattern = "";
76
77 if (type == "fasta") { pattern = "[filename],[distance],[group],shared.fasta"; }
78 else if (type == "accnos") { pattern = "[filename],[distance],[group],accnos"; }
79 else if (type == "sharedseqs") { pattern = "[filename],[distance],[group],shared.seqs"; }
80 else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->setControl_pressed(true); }
81
82 return pattern;
83 }
84 catch(exception& e) {
85 m->errorOut(e, "GetSharedOTUCommand", "getOutputPattern");
86 exit(1);
87 }
88 }
89 //**********************************************************************************************************************
GetSharedOTUCommand(string option)90 GetSharedOTUCommand::GetSharedOTUCommand(string option) : Command() {
91 try {
92 if(option == "help") { help(); abort = true; calledHelp = true; }
93 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
94 else if(option == "category") { abort = true; calledHelp = true; }
95
96 else {
97 OptionParser parser(option, setParameters());
98 map<string,string> parameters = parser.getParameters();
99
100 ValidParameters validParameter;
101
102
103 //check for required parameters
104 listfile = validParameter.validFile(parameters, "list");
105 if (listfile == "not open") { abort = true; }
106 else if (listfile == "not found") { listfile = ""; }
107 else { format = "list"; current->setListFile(listfile); }
108
109 groupfile = validParameter.validFile(parameters, "group");
110 if (groupfile == "not open") { abort = true; }
111 else if (groupfile == "not found") { groupfile = ""; }
112 else { current->setGroupFile(groupfile); }
113
114 sharedfile = validParameter.validFile(parameters, "shared");
115 if (sharedfile == "not open") { abort = true; }
116 else if (sharedfile == "not found") { sharedfile = ""; }
117 else { current->setSharedFile(sharedfile); }
118
119 fastafile = validParameter.validFile(parameters, "fasta");
120 if (fastafile == "not open") { abort = true; }
121 else if (fastafile == "not found") { fastafile = ""; }
122 else { current->setFastaFile(fastafile); }
123
124 countfile = validParameter.validFile(parameters, "count");
125 if (countfile == "not open") { countfile = ""; abort = true; }
126 else if (countfile == "not found") { countfile = ""; }
127 else {
128 current->setCountFile(countfile);
129 CountTable temp;
130 if (!temp.testGroups(countfile)) { m->mothurOut("[ERROR]: Your count file does not have group info, aborting.\n"); abort=true; }
131 }
132
133 if ((sharedfile == "") && (listfile == "")) { //look for currents
134 //is there are current file available for either of these?
135 //give priority to shared, then list
136 sharedfile = current->getSharedFile();
137 if (sharedfile != "") { m->mothurOut("Using " + sharedfile + " as input file for the shared parameter.\n"); }
138 else {
139 listfile = current->getListFile();
140 if (listfile != "") { m->mothurOut("Using " + listfile + " as input file for the list parameter.\n"); }
141 else {
142 m->mothurOut("No valid current files. You must provide a shared or list file.\n");
143 abort = true;
144 }
145 }
146 }else if ((sharedfile != "") && (listfile != "")) {
147 m->mothurOut("You may enter ONLY ONE of the following: shared or list.\n"); abort = true;
148 }
149
150 if (listfile != "") {
151 if ((groupfile == "") && (countfile == "")) {
152 groupfile = current->getGroupFile();
153 if (groupfile != "") { m->mothurOut("Using " + groupfile + " as input file for the group parameter.\n"); }
154 else {
155 countfile = current->getCountFile();
156 if (countfile != "") { m->mothurOut("Using " + countfile + " as input file for the count parameter.\n"); }
157 else {
158 m->mothurOut("You need to provide a groupfile or countfile if you are going to use the list format.\n");
159 abort = true;
160 }
161 }
162 }
163 }
164
165 if ((sharedfile != "") && (fastafile != "")) { m->mothurOut("You cannot use the fasta file with the shared file.\n"); abort = true; }
166
167 //check for optional parameter and set defaults
168 // ...at some point should added some additional type checking...
169 label = validParameter.valid(parameters, "label");
170 if (label == "not found") { label = ""; }
171 else {
172 if(label != "all") { util.splitAtDash(label, labels); allLines = false; }
173 else { allLines = true; }
174 }
175
176 output = validParameter.valid(parameters, "output");
177 if (output == "not found") { output = ""; }
178 else if (output == "default") { output = ""; }
179
180 groups = validParameter.valid(parameters, "uniquegroups");
181 if (groups == "not found") { groups = ""; }
182 else {
183 userGroups = "unique." + groups;
184 util.splitAtDash(groups, Groups);
185 if (Groups.size() != 0) { if (Groups[0]== "all") { Groups.clear(); } }
186 if (Groups.size() > 4) { userGroups = "unique.selected_groups"; } //if too many groups then the filename becomes too big.
187 }
188
189 groups = validParameter.valid(parameters, "sharedgroups");
190 if (groups == "not found") { groups = ""; }
191 else {
192 userGroups = groups;
193 util.splitAtDash(groups, Groups);
194 if (Groups.size() != 0) { if (Groups[0]== "all") { Groups.clear(); } }
195 if (Groups.size() > 4) { userGroups = "selected_groups"; } //if too many groups then the filename becomes too big.
196 unique = false;
197 }
198
199 }
200
201 }
202 catch(exception& e) {
203 m->errorOut(e, "GetSharedOTUCommand", "GetSharedOTUCommand");
204 exit(1);
205 }
206 }
207 //**********************************************************************************************************************
208
execute()209 int GetSharedOTUCommand::execute(){
210 try {
211
212 if (abort) { if (calledHelp) { return 0; } return 2; }
213
214 if ( sharedfile != "") { runShared(); }
215 else {
216 if (groupfile != "") {
217 groupMap = new GroupMap(groupfile);
218
219 int groupError = groupMap->readMap();
220 if (groupError == 1) { delete groupMap; return 0; }
221 vector<string> allGroups = groupMap->getNamesOfGroups();
222 }else{
223 ct = new CountTable();
224 ct->readTable(countfile, true, false);
225 }
226
227 if (m->getControl_pressed()) { delete groupMap; return 0; }
228
229 if (Groups.size() == 0) {
230 if (groupfile != "") { Groups = groupMap->getNamesOfGroups(); }
231 else { Groups = ct->getNamesOfGroups(); }
232
233 //make string for outputfile name
234 userGroups = "unique.";
235 for(int i = 0; i < Groups.size(); i++) { userGroups += Groups[i] + "-"; }
236 userGroups = userGroups.substr(0, userGroups.length()-1);
237 if (Groups.size() > 4) { userGroups = "unique.selected_groups"; } //if too many groups then the filename becomes too big.
238 }
239
240 //put groups in map to find easier
241 for(int i = 0; i < Groups.size(); i++) { groupFinder[Groups[i]] = Groups[i]; }
242
243 if (fastafile != "") {
244 ifstream inFasta;
245 util.openInputFile(fastafile, inFasta);
246
247 while(!inFasta.eof()) {
248 if (m->getControl_pressed()) { outputTypes.clear(); inFasta.close(); delete groupMap; return 0; }
249
250 Sequence seq(inFasta); util.gobble(inFasta);
251 if (seq.getName() != "") { seqs.push_back(seq); }
252 }
253 inFasta.close();
254 }
255
256 InputData input(listfile, "list", nullVector);
257 set<string> processedLabels;
258 set<string> userLabels = labels;
259 string lastLabel = "";
260
261 ListVector* list = util.getNextList(input, allLines, userLabels, processedLabels, lastLabel);
262
263 while (list != NULL) {
264
265 if (m->getControl_pressed()) { delete list; break; }
266
267 process(list); delete list;
268
269 list = util.getNextList(input, allLines, userLabels, processedLabels, lastLabel);
270 }
271
272 if (m->getControl_pressed()) { outputTypes.clear(); for (int i = 0; i < outputNames.size(); i++) { util.mothurRemove(outputNames[i]); } if (groupfile != "") { delete groupMap; }else { delete ct; } return 0; }
273 }
274 //set fasta file as new current fastafile
275 string currentName = "";
276 itTypes = outputTypes.find("fasta");
277 if (itTypes != outputTypes.end()) {
278 if ((itTypes->second).size() != 0) { currentName = (itTypes->second)[0]; current->setFastaFile(currentName); }
279 }
280
281 if (output == "accnos") {
282 itTypes = outputTypes.find("accnos");
283 if (itTypes != outputTypes.end()) {
284 if ((itTypes->second).size() != 0) { currentName = (itTypes->second)[0]; current->setAccnosFile(currentName); }
285 }
286 }
287
288 m->mothurOut("\nOutput File Names: \n");
289 for (int i = 0; i < outputNames.size(); i++) { m->mothurOut(outputNames[i] +"\n"); } m->mothurOutEndLine();
290
291
292 return 0;
293 }
294
295 catch(exception& e) {
296 m->errorOut(e, "GetSharedOTUCommand", "execute");
297 exit(1);
298 }
299 }
300 /***********************************************************/
process(ListVector * shared)301 int GetSharedOTUCommand::process(ListVector* shared) {
302 try {
303
304 map<string, string> fastaMap;
305
306 ofstream outNames;
307 string outputFileNames;
308
309 if (outputdir == "") { outputdir += util.hasPath(listfile); }
310 map<string, string> variables;
311 variables["[filename]"] = outputdir + util.getRootName(util.getSimpleName(listfile));
312 variables["[distance]"] = shared->getLabel();
313 variables["[group]"] = userGroups;
314 if (output != "accnos") { outputFileNames = getOutputFileName("sharedseqs", variables); }
315 else { outputFileNames = getOutputFileName("accnos", variables); }
316
317 util.openOutputFile(outputFileNames, outNames);
318
319 bool wroteSomething = false;
320 int num = 0;
321
322 //go through each bin, find out if shared
323 vector<string> binLabels = shared->getLabels();
324 for (int i = 0; i < shared->getNumBins(); i++) {
325 if (m->getControl_pressed()) { outNames.close(); util.mothurRemove(outputFileNames); return 0; }
326
327 bool uniqueOTU = true;
328
329 map<string, int> atLeastOne;
330 for (int f = 0; f < Groups.size(); f++) { atLeastOne[Groups[f]] = 0; }
331
332 vector<string> namesOfSeqsInThisBin;
333
334 string names = shared->get(i);
335 vector<string> binNames;
336 util.splitAtComma(names, binNames);
337 for(int j = 0; j < binNames.size(); j++) {
338 string name = binNames[j];
339
340 //find group
341 string seqGroup = "not found"; vector<string> seqsGroups;
342 if (groupfile != "") { seqGroup = groupMap->getGroup(name); }
343 else {
344 seqsGroups = ct->getGroups(name);
345 seqGroup = util.getStringFromVector(seqsGroups, "-");
346 }
347
348 if (output != "accnos") {
349 namesOfSeqsInThisBin.push_back((name + "|" + seqGroup + "|" + binLabels[i]));
350 }else { namesOfSeqsInThisBin.push_back(name); }
351
352 if (seqGroup == "not found") { m->mothurOut(name + " is not in your groupfile. Please correct.\n"); exit(1); }
353
354 if (groupfile != "") {
355 //is this seq in one of hte groups we care about
356 it = groupFinder.find(seqGroup);
357 if (it == groupFinder.end()) { uniqueOTU = false; } //you have a sequence from a group you don't want
358 else { atLeastOne[seqGroup]++; }
359 }else {
360 for (int k = 0; k < seqsGroups.size(); k++) {
361 //is this seq in one of hte groups we care about
362 it = groupFinder.find(seqsGroups[k]);
363 if (it == groupFinder.end()) { uniqueOTU = false; } //you have a sequence from a group you don't want
364 else { atLeastOne[seqsGroups[k]]++; }
365 }
366 }
367 }
368
369 //make sure you have at least one seq from each group you want
370 bool sharedByAll = true;
371 map<string, int>::iterator it2;
372 for (it2 = atLeastOne.begin(); it2 != atLeastOne.end(); it2++) {
373 if (it2->second == 0) { sharedByAll = false; }
374 }
375
376 //if the user wants unique bins and this is unique then print
377 //or this the user wants shared bins and this bin is shared then print
378 if ((unique && uniqueOTU && sharedByAll) || (!unique && sharedByAll)) {
379
380 wroteSomething = true;
381 num++;
382
383 //output list of names
384 for (int j = 0; j < namesOfSeqsInThisBin.size(); j++) {
385 outNames << namesOfSeqsInThisBin[j] << endl;
386
387 if (fastafile != "") {
388 if (output != "accnos") {
389 string seqName = namesOfSeqsInThisBin[j].substr(0,namesOfSeqsInThisBin[j].find_last_of('|'));
390 seqName = seqName.substr(0,seqName.find_last_of('|'));
391 fastaMap[seqName] = namesOfSeqsInThisBin[j]; //fastaMap needs to contain just the seq name for output later
392 }else {
393 fastaMap[namesOfSeqsInThisBin[j]] = namesOfSeqsInThisBin[j];
394 }
395 }
396 }
397 }
398 }
399
400 outNames.close();
401
402 if (!wroteSomething) {
403 util.mothurRemove(outputFileNames);
404 string outputString = "\t" + toString(num) + " - No otus shared by groups";
405
406 string groupString = "";
407 for (int h = 0; h < Groups.size(); h++) {
408 groupString += " " + Groups[h];
409 }
410
411 outputString += groupString + ".";
412 m->mothurOut(outputString); m->mothurOutEndLine();
413 }else {
414 m->mothurOut("\t" + toString(num)); m->mothurOutEndLine();
415 outputNames.push_back(outputFileNames);
416 if (output != "accnos") { outputTypes["sharedseqs"].push_back(outputFileNames); }
417 else { outputTypes["accnos"].push_back(outputFileNames); }
418 }
419
420 //if fasta file provided output new fasta file
421 if ((fastafile != "") && wroteSomething) {
422 if (outputdir == "") { outputdir += util.hasPath(fastafile); }
423 variables["[filename]"] = outputdir + util.getRootName(util.getSimpleName(fastafile));
424 string outputFileFasta = getOutputFileName("fasta", variables);
425 ofstream outFasta;
426 util.openOutputFile(outputFileFasta, outFasta);
427 outputNames.push_back(outputFileFasta); outputTypes["fasta"].push_back(outputFileFasta);
428
429 for (int k = 0; k < seqs.size(); k++) {
430 if (m->getControl_pressed()) { outFasta.close(); return 0; }
431
432 //if this is a sequence we want, output it
433 it = fastaMap.find(seqs[k].getName());
434 if (it != fastaMap.end()) {
435
436 if (output != "accnos") {
437 outFasta << ">" << it->second << endl;
438 }else {
439 outFasta << ">" << it->first << endl;
440 }
441
442 outFasta << seqs[k].getAligned() << endl;
443 }
444 }
445
446 outFasta.close();
447 }
448
449 return 0;
450
451 }
452 catch(exception& e) {
453 m->errorOut(e, "GetSharedOTUCommand", "process");
454 exit(1);
455 }
456 }
457 /***********************************************************/
runShared()458 int GetSharedOTUCommand::runShared() {
459 try {
460 InputData input(sharedfile, "sharedfile", nullVector);
461 set<string> processedLabels;
462 set<string> userLabels = labels;
463 string lastLabel = "";
464
465 SharedRAbundVectors* lookup = util.getNextShared(input, allLines, userLabels, processedLabels, lastLabel);
466 //Groups = lookup->getNamesGroups();
467
468 if (userGroups == "") {
469 //make string for outputfile name
470 userGroups = "unique.";
471 for(int i = 0; i < Groups.size(); i++) { userGroups += Groups[i] + "-"; }
472 userGroups = userGroups.substr(0, userGroups.length()-1);
473 if (Groups.size() > 4) { userGroups = "unique.selected_groups"; } //if too many groups then the filename becomes too big.
474 }
475
476 //put groups in map to find easier
477 for(int i = 0; i < Groups.size(); i++) { groupFinder[Groups[i]] = Groups[i];}
478
479 while (lookup != NULL) {
480
481 if (m->getControl_pressed()) { delete lookup; break; }
482
483 process(lookup); delete lookup;
484
485 lookup = util.getNextShared(input, allLines, userLabels, processedLabels, lastLabel);
486 }
487
488 if (m->getControl_pressed()) { outputTypes.clear(); for (int i = 0; i < outputNames.size(); i++) { util.mothurRemove(outputNames[i]); } return 0; }
489
490
491 return 0;
492
493 }
494 catch(exception& e) {
495 m->errorOut(e, "GetSharedOTUCommand", "runShared");
496 exit(1);
497 }
498 }
499 /***********************************************************/
process(SharedRAbundVectors * & lookup)500 int GetSharedOTUCommand::process(SharedRAbundVectors*& lookup) {
501 try {
502
503 string outputFileNames;
504 if (outputdir == "") { outputdir += util.hasPath(sharedfile); }
505 map<string, string> variables;
506 variables["[filename]"] = outputdir + util.getRootName(util.getSimpleName(sharedfile));
507 variables["[distance]"] = lookup->getLabel();
508 variables["[group]"] = userGroups;
509 if (output != "accnos") { outputFileNames = getOutputFileName("sharedseqs", variables); }
510 else { outputFileNames = getOutputFileName("accnos", variables); }
511
512 ofstream outNames;
513 util.openOutputFile(outputFileNames, outNames);
514
515 bool wroteSomething = false;
516 int num = 0;
517
518 //go through each bin, find out if shared
519 for (int i = 0; i < lookup->getNumBins(); i++) {
520 if (m->getControl_pressed()) { outNames.close(); util.mothurRemove(outputFileNames); return 0; }
521
522 bool uniqueOTU = true;
523 map<string, int> atLeastOne;
524 for (int f = 0; f < Groups.size(); f++) { atLeastOne[Groups[f]] = 0; }
525
526 set<string> namesOfGroupsInThisBin;
527
528 vector<string> groupNames = lookup->getNamesGroups();
529 for(int j = 0; j < lookup->size(); j++) {
530 string seqGroup = groupNames[j];
531 string name = lookup->getOTUName(i);
532 int abund = lookup->get(i, seqGroup);
533
534 if (abund != 0) {
535 if (output != "accnos") {
536 namesOfGroupsInThisBin.insert(name + "|" + seqGroup + "|" + toString(abund));
537 }else { namesOfGroupsInThisBin.insert(name); }
538
539 //is this seq in one of the groups we care about
540 it = groupFinder.find(seqGroup);
541 if (it == groupFinder.end()) { uniqueOTU = false; } //you have sequences from a group you don't want
542 else { atLeastOne[seqGroup]++; }
543 }
544 }
545
546 //make sure you have at least one seq from each group you want
547 bool sharedByAll = true;
548 map<string, int>::iterator it2;
549 for (it2 = atLeastOne.begin(); it2 != atLeastOne.end(); it2++) {
550 if (it2->second == 0) { sharedByAll = false; }
551 }
552
553 //if the user wants unique bins and this is unique then print
554 //or this the user wants shared bins and this bin is shared then print
555 if ((unique && uniqueOTU && sharedByAll) || (!unique && sharedByAll)) {
556
557 wroteSomething = true;
558 num++;
559
560 //output list of names
561 for (set<string>::iterator itNames = namesOfGroupsInThisBin.begin(); itNames != namesOfGroupsInThisBin.end(); itNames++) {
562 outNames << (*itNames) << endl;
563 }
564 }
565 }
566 outNames.close();
567
568 if (!wroteSomething) {
569 util.mothurRemove(outputFileNames);
570 string outputString = "\t" + toString(num) + " - No otus shared by groups";
571
572 string groupString = "";
573 for (int h = 0; h < Groups.size(); h++) {
574 groupString += " " + Groups[h];
575 }
576
577 outputString += groupString + ".";
578 m->mothurOut(outputString); m->mothurOutEndLine();
579 }else {
580 m->mothurOut("\t" + toString(num)); m->mothurOutEndLine();
581 outputNames.push_back(outputFileNames);
582 if (output != "accnos") { outputTypes["sharedseqs"].push_back(outputFileNames); }
583 else { outputTypes["accnos"].push_back(outputFileNames); }
584 }
585
586 return 0;
587 }
588 catch(exception& e) {
589 m->errorOut(e, "GetSharedOTUCommand", "process");
590 exit(1);
591 }
592 }
593
594 //**********************************************************************************************************************
595