]> git.donarmstrong.com Git - mothur.git/blob - sharedcommand.cpp
added load.logfile command. changed summary.single output for subsample=t.
[mothur.git] / sharedcommand.cpp
1 /*
2  *  sharedcommand.cpp
3  *  Dotur
4  *
5  *  Created by Sarah Westcott on 1/2/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "sharedcommand.h"
11 #include "sharedutilities.h"
12
13 //********************************************************************************************************************
14 //sorts lowest to highest
15 inline bool compareSharedRabunds(SharedRAbundVector* left, SharedRAbundVector* right){
16         return (left->getGroup() < right->getGroup());  
17 }
18 //**********************************************************************************************************************
19 vector<string> SharedCommand::setParameters(){  
20         try {
21         CommandParameter pbiom("biom", "InputTypes", "", "", "BiomListGroup", "BiomListGroup", "none",false,false); parameters.push_back(pbiom);
22                 CommandParameter plist("list", "InputTypes", "", "", "BiomListGroup", "BiomListGroup", "ListGroup",false,false); parameters.push_back(plist);
23                 CommandParameter pgroup("group", "InputTypes", "", "", "none", "none", "ListGroup",false,false); parameters.push_back(pgroup);
24                 //CommandParameter pordergroup("ordergroup", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(pordergroup);
25                 CommandParameter plabel("label", "String", "", "", "", "", "",false,false); parameters.push_back(plabel);
26                 CommandParameter pgroups("groups", "String", "", "", "", "", "",false,false); parameters.push_back(pgroups);
27                 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "",false,false); parameters.push_back(pinputdir);
28                 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "",false,false); parameters.push_back(poutputdir);
29                 
30                 vector<string> myArray;
31                 for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
32                 return myArray;
33         }
34         catch(exception& e) {
35                 m->errorOut(e, "SharedCommand", "setParameters");
36                 exit(1);
37         }
38 }
39 //**********************************************************************************************************************
40 string SharedCommand::getHelpString(){  
41         try {
42                 string helpString = "";
43                 helpString += "The make.shared command reads a list and group file or a biom file and creates a shared file. If a list and group are provided a rabund file is created for each group.\n";
44                 helpString += "The make.shared command parameters are list, group, biom, groups and label. list and group are required unless a current file is available or you provide a biom file.\n";
45                 helpString += "The groups parameter allows you to indicate which groups you want to include, group names should be separated by dashes. ex. groups=A-B-C. Default is all groups in your groupfile.\n";
46                 helpString += "The label parameter is only valid with the list and group option and allows you to indicate which labels you want to include, label names should be separated by dashes. Default is all labels in your list file.\n";
47                 //helpString += "The ordergroup parameter allows you to indicate the order of the groups in the sharedfile, by default the groups are listed alphabetically.\n";
48                 return helpString;
49         }
50         catch(exception& e) {
51                 m->errorOut(e, "SharedCommand", "getHelpString");
52                 exit(1);
53         }
54 }
55 //**********************************************************************************************************************
56 string SharedCommand::getOutputFileNameTag(string type, string inputName=""){   
57         try {
58         string outputFileName = "";
59                 map<string, vector<string> >::iterator it;
60         
61         //is this a type this command creates
62         it = outputTypes.find(type);
63         if (it == outputTypes.end()) {  m->mothurOut("[ERROR]: this command doesn't create a " + type + " output file.\n"); }
64         else {
65             if (type == "shared")            {   outputFileName =  "shared";   }
66             else if (type == "rabund")    {   outputFileName =  "rabund";   }
67             else if (type == "group")        {   outputFileName =  "groups";   }
68             else { m->mothurOut("[ERROR]: No definition for type " + type + " output file tag.\n"); m->control_pressed = true;  }
69         }
70         return outputFileName;
71         }
72         catch(exception& e) {
73                 m->errorOut(e, "SharedCommand", "getOutputFileNameTag");
74                 exit(1);
75         }
76 }
77
78 //**********************************************************************************************************************
79 SharedCommand::SharedCommand(){ 
80         try {
81                 abort = true; calledHelp = true; 
82                 setParameters();
83                 //initialize outputTypes
84                 vector<string> tempOutNames;
85                 outputTypes["rabund"] = tempOutNames;
86                 outputTypes["shared"] = tempOutNames;
87                 outputTypes["group"] = tempOutNames;
88         }
89         catch(exception& e) {
90                 m->errorOut(e, "SharedCommand", "SharedCommand");
91                 exit(1);
92         }
93 }
94 //**********************************************************************************************************************
95 SharedCommand::SharedCommand(string option)  {
96         try {
97                 abort = false; calledHelp = false;   
98                 allLines = 1;
99                 
100                 //allow user to run help
101                 if(option == "help") { help(); abort = true; calledHelp = true; }
102                 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
103                 
104                 else {
105                         
106                          vector<string> myArray = setParameters();
107                          
108                          OptionParser parser(option);
109                          map<string, string> parameters = parser.getParameters();
110                          
111                          ValidParameters validParameter;
112                          map<string, string>::iterator it;
113                          
114                          //check to make sure all parameters are valid for command
115                          for (it = parameters.begin(); it != parameters.end(); it++) { 
116                                  if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
117                          }
118                          
119                          //if the user changes the input directory command factory will send this info to us in the output parameter 
120                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
121                          if (inputDir == "not found"){  inputDir = "";          }
122                          else {
123                                  string path;
124                                  it = parameters.find("list");
125                                  //user has given a template file
126                                  if(it != parameters.end()){ 
127                                          path = m->hasPath(it->second);
128                                          //if the user has not given a path then, add inputdir. else leave path alone.
129                                          if (path == "") {      parameters["list"] = inputDir + it->second;             }
130                                  }
131                          
132                                  it = parameters.find("group");
133                                  //user has given a template file
134                                  if(it != parameters.end()){ 
135                                          path = m->hasPath(it->second);
136                                          //if the user has not given a path then, add inputdir. else leave path alone.
137                                          if (path == "") {      parameters["group"] = inputDir + it->second;            }
138                                  }
139                          
140                                  /*it = parameters.find("ordergroup");
141                                  //user has given a template file
142                                  if(it != parameters.end()){ 
143                                          path = m->hasPath(it->second);
144                                          //if the user has not given a path then, add inputdir. else leave path alone.
145                                          if (path == "") {      parameters["ordergroup"] = inputDir + it->second;               }
146                                  }*/
147                  
148                  it = parameters.find("biom");
149                                  //user has given a template file
150                                  if(it != parameters.end()){ 
151                                          path = m->hasPath(it->second);
152                                          //if the user has not given a path then, add inputdir. else leave path alone.
153                                          if (path == "") {      parameters["biom"] = inputDir + it->second;             }
154                                  }
155                          }
156                          
157              vector<string> tempOutNames;
158              outputTypes["rabund"] = tempOutNames;
159              outputTypes["shared"] = tempOutNames;
160              outputTypes["group"] = tempOutNames;
161                          
162                          //if the user changes the output directory command factory will send this info to us in the output parameter 
163                          outputDir = validParameter.validFile(parameters, "outputdir", false);          if (outputDir == "not found"){  outputDir = ""; }
164                          
165                          //check for required parameters
166                          listfile = validParameter.validFile(parameters, "list", true);
167                          if (listfile == "not open") { listfile = ""; abort = true; }
168                          else if (listfile == "not found") { listfile = "";  }
169                          else { m->setListFile(listfile); }     
170             
171              biomfile = validParameter.validFile(parameters, "biom", true);
172              if (biomfile == "not open") { biomfile = ""; abort = true; }
173              else if (biomfile == "not found") { biomfile = "";  }
174              else { m->setBiomFile(biomfile); }         
175                                                         
176                          ordergroupfile = validParameter.validFile(parameters, "ordergroup", true);
177                          if (ordergroupfile == "not open") { abort = true; }    
178                          else if (ordergroupfile == "not found") { ordergroupfile = ""; }
179                                                  
180                          groupfile = validParameter.validFile(parameters, "group", true);
181                          if (groupfile == "not open") { groupfile = ""; abort = true; } 
182                          else if (groupfile == "not found") { groupfile = ""; }
183                          else {  m->setGroupFile(groupfile); }
184                          
185             if ((biomfile == "") && (listfile == "")) { 
186                                 //is there are current file available for either of these?
187                                 //give priority to list, then biom
188                                 listfile = m->getListFile(); 
189                                 if (listfile != "") {  m->mothurOut("Using " + listfile + " as input file for the list parameter."); m->mothurOutEndLine(); }
190                                 else { 
191                                         biomfile = m->getBiomFile(); 
192                                         if (biomfile != "") {  m->mothurOut("Using " + biomfile + " as input file for the biom parameter."); m->mothurOutEndLine(); }
193                                         else { 
194                                                 m->mothurOut("No valid current files. You must provide a list or biom file before you can use the make.shared command."); m->mothurOutEndLine(); 
195                                                 abort = true;
196                                         }
197                                 }
198                         }
199                         else if ((biomfile != "") && (listfile != "")) { m->mothurOut("When executing a make.shared command you must enter ONLY ONE of the following: list or biom."); m->mothurOutEndLine(); abort = true; }
200                         
201                         if (listfile != "") {
202                                 if (groupfile == "") { 
203                                         groupfile = m->getGroupFile(); 
204                                         if (groupfile != "") {  m->mothurOut("Using " + groupfile + " as input file for the group parameter."); m->mothurOutEndLine(); }
205                                         else { 
206                                                 m->mothurOut("You need to provide a groupfle if you are going to use the list format."); m->mothurOutEndLine(); 
207                                                 abort = true; 
208                                         }       
209                                 }
210                         }
211
212                         
213                          string groups = validParameter.validFile(parameters, "groups", false);                 
214                          if (groups == "not found") { groups = ""; }
215                          else { 
216                                  m->splitAtDash(groups, Groups);
217                                  m->setGroups(Groups);
218                          }
219                          
220                          //check for optional parameter and set defaults
221                          // ...at some point should added some additional type checking...
222                          string label = validParameter.validFile(parameters, "label", false);                   
223                          if (label == "not found") { label = ""; }
224                          else { 
225                                  if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }
226                                  else { allLines = 1;  }
227                          }
228                 }
229                 
230         }
231         catch(exception& e) {
232                 m->errorOut(e, "SharedCommand", "SharedCommand");
233                 exit(1);
234         }
235 }
236 //**********************************************************************************************************************
237
238 int SharedCommand::execute(){
239         try {
240                 
241                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
242                         
243                 //getting output filename
244         string filename = "";
245                 if (listfile != "") { filename = listfile; }
246         else { filename = biomfile; }
247                 
248                 if (outputDir == "") { outputDir += m->hasPath(filename); }
249                 
250                 filename = outputDir + m->getRootName(m->getSimpleName(filename));
251                 filename = filename + getOutputFileNameTag("shared");
252                 outputNames.push_back(filename); outputTypes["shared"].push_back(filename);
253                 
254         if (listfile != "") {  createSharedFromListGroup(filename);  }
255         else {   createSharedFromBiom(filename);  }
256         
257         if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) {        m->mothurRemove(outputNames[i]); }  }
258         
259                 //set rabund file as new current rabundfile
260                 string current = "";
261                 itTypes = outputTypes.find("rabund");
262                 if (itTypes != outputTypes.end()) {
263                         if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setRabundFile(current); }
264                 }
265                 
266                 itTypes = outputTypes.find("shared");
267                 if (itTypes != outputTypes.end()) {
268                         if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setSharedFile(current); }
269                 }       
270                 
271                 itTypes = outputTypes.find("group");
272                 if (itTypes != outputTypes.end()) {
273                         if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setGroupFile(current); }
274                 }
275                 
276                 m->mothurOutEndLine();
277                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
278                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }
279                 m->mothurOutEndLine();
280                 
281                 return 0;
282         }
283         catch(exception& e) {
284                 m->errorOut(e, "SharedCommand", "execute");
285                 exit(1);
286         }
287 }
288 //**********************************************************************************************************************
289 int SharedCommand::createSharedFromBiom(string filename) {
290         try {
291         ofstream out;
292         m->openOutputFile(filename, out);
293         
294         /*{
295             "id":"/Users/SarahsWork/Desktop/release/temp.job2.shared-unique",
296             "format": "Biological Observation Matrix 0.9.1",
297             "format_url": "http://biom-format.org",
298             "type": "OTU table",
299             "generated_by": "mothur1.24.0",
300             "date": "Tue Apr 17 13:12:07 2012", */
301         
302         ifstream in;
303         m->openInputFile(biomfile, in);
304         
305         m->getline(in); m->gobble(in);  //grab first '{'
306         
307         string matrixFormat = "";
308         int numRows = 0;
309         int numCols = 0;
310         int shapeNumRows = 0;
311         int shapeNumCols = 0;
312         vector<string> otuNames;
313         vector<string> groupNames;
314         while (!in.eof()) {
315             
316             if (m->control_pressed) { break; }
317             
318             string line = m->getline(in); m->gobble(in);
319             
320             string tag = getTag(line);
321             
322             if (tag == "type") {
323                 //check to make sure this is an OTU table
324                 string type = getTag(line);
325                 if (type != "OTU table") { m->mothurOut("[ERROR]: " + type + " is not a valid biom type for mothur. Only type allowed is OTU table.\n"); m->control_pressed = true; }
326             }else if (tag == "matrix_type") {
327                 //get type and check type
328                 matrixFormat = getTag(line);
329                 if ((matrixFormat != "sparse") && (matrixFormat != "dense")) { m->mothurOut("[ERROR]: " + matrixFormat + " is not a valid biom matrix_type for mothur. Types allowed are sparse and dense.\n"); m->control_pressed = true; }
330             }else if (tag == "matrix_element_type") {
331                 //get type and check type
332                 string matrixElementType = getTag(line);
333                 if (matrixElementType != "int") { m->mothurOut("[ERROR]: " + matrixElementType + " is not a valid matrix_element_type for mothur. Only type allowed is int.\n"); m->control_pressed = true; }
334             }else if (tag == "rows") {
335                 //read otu names
336                 otuNames = readRows(line, in, numRows);  
337             }else if (tag == "columns") {
338                 //read sample names
339                 groupNames = readRows(line, in, numCols); 
340                 
341                 //if users selected groups, then remove the groups not wanted.
342                 SharedUtil util;
343                 vector<string> Groups = m->getGroups();
344                 vector<string> allGroups = groupNames;
345                 util.setGroups(Groups, allGroups);
346                 m->setGroups(Groups);
347                 
348                 //fill filehandles with neccessary ofstreams
349                 int i;
350                 ofstream* temp;
351                 for (i=0; i<Groups.size(); i++) {
352                     temp = new ofstream;
353                     filehandles[Groups[i]] = temp;
354                 }
355                 
356                 //set fileroot
357                 fileroot = outputDir + m->getRootName(m->getSimpleName(biomfile));
358                 
359                 //clears file before we start to write to it below
360                 for (int i=0; i<Groups.size(); i++) {
361                     m->mothurRemove((fileroot + Groups[i] + ".rabund"));
362                     outputNames.push_back((fileroot + Groups[i] + ".rabund"));
363                     outputTypes["rabund"].push_back((fileroot + Groups[i] + ".rabund"));
364                 }
365
366             }else if (tag == "shape") {
367                 getDims(line, shapeNumRows, shapeNumCols);
368                 
369                 //check shape
370                 if (shapeNumCols != numCols) {
371                     m->mothurOut("[ERROR]: shape indicates " + toString(shapeNumCols) + " columns, but I only read " + toString(numCols) + " columns.\n"); m->control_pressed = true;
372                 }
373                 
374                 if (shapeNumRows != numRows) {
375                     m->mothurOut("[ERROR]: shape indicates " + toString(shapeNumRows) + " rows, but I only read " + toString(numRows) + " rows.\n"); m->control_pressed = true;
376                 }
377             }else if (tag == "data") {
378                 m->currentBinLabels = otuNames;
379                 
380                 //read data
381                 vector<SharedRAbundVector*> lookup = readData(matrixFormat, line, in, groupNames, otuNames.size());
382
383                 m->mothurOutEndLine(); m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
384                 lookup[0]->printHeaders(out); 
385                 printSharedData(lookup, out);
386             }
387         }
388         in.close();
389         
390                 
391         return 0;
392     }
393         catch(exception& e) {
394                 m->errorOut(e, "SharedCommand", "createSharedFromBiom");
395                 exit(1);
396         }
397 }
398 //**********************************************************************************************************************
399 vector<SharedRAbundVector*> SharedCommand::readData(string matrixFormat, string line, ifstream& in, vector<string>& groupNames, int numOTUs) {
400         try {
401         
402         vector<SharedRAbundVector*> lookup; 
403         
404         //creates new sharedRAbunds
405         for (int i = 0; i < groupNames.size(); i++) {
406             SharedRAbundVector* temp = new SharedRAbundVector(numOTUs); //sets all abunds to 0
407             temp->setLabel("dummy");
408             temp->setGroup(groupNames[i]);
409             lookup.push_back(temp);
410         }
411         
412         bool dataStart = false;
413         bool inBrackets = false;
414         string num = "";
415         vector<int> nums;
416         int otuCount = 0;
417         for (int i = 0; i < line.length(); i++) {
418             
419             if (m->control_pressed) { return lookup; }
420             
421             //look for opening [ to indicate data is starting
422             if ((line[i] == '[') && (!dataStart)) { dataStart = true; i++;  if (!(i < line.length())) { break; } }
423             else if ((line[i] == ']') && dataStart && (!inBrackets)) { break; } //we are done reading data
424                 
425             if (dataStart) {
426                 if ((line[i] == '[') && (!inBrackets)) { inBrackets = true; i++;  if (!(i < line.length())) { break; } }
427                 else if ((line[i] == ']') && (inBrackets)) { 
428                     inBrackets = false; 
429                     int temp;
430                     m->mothurConvert(num, temp);
431                     nums.push_back(temp);
432                     num = "";
433                     
434                     //save info to vectors
435                     if (matrixFormat == "dense") {
436                         
437                         //sanity check
438                         if (nums.size() != lookup.size()) { m->mothurOut("[ERROR]: trouble parsing OTU data.  OTU " + toString(otuCount) + " causing errors.\n"); m->control_pressed = true; }
439                         
440                         //set abundances for this otu
441                         //nums contains [abundSample0, abundSample1, abundSample2, ...] for current OTU
442                         for (int j = 0; j < lookup.size(); j++) { lookup[j]->set(otuCount, nums[j], groupNames[j]); }
443                         
444                         otuCount++;
445                     }else {
446                         //sanity check
447                         if (nums.size() != 3) { m->mothurOut("[ERROR]: trouble parsing OTU data.\n"); m->control_pressed = true; }
448                         
449                         //nums contains [otuNum, sampleNum, abundance]
450                         lookup[nums[1]]->set(nums[0], nums[2], groupNames[nums[1]]);
451                     }
452                     nums.clear();
453                 }
454                 
455                 if (inBrackets) {
456                     if (line[i] == ',') {
457                         int temp;
458                         m->mothurConvert(num, temp);
459                         nums.push_back(temp);
460                         num = "";
461                     }else { if (!isspace(line[i])) { num += line[i]; }  }
462                 }
463             }
464         }
465         
466         //same as above just reading from file.
467         while (!in.eof()) {
468             
469             char c = in.get(); m->gobble(in);
470             
471             if (m->control_pressed) { return lookup; }
472             
473             //look for opening [ to indicate data is starting
474             if ((c == '[') && (!dataStart)) { dataStart = true; c = in.get();  if (in.eof()) { break; } }
475             else if ((c == ']') && dataStart && (!inBrackets)) { break; } //we are done reading data
476               
477             if (dataStart) {
478                 if ((c == '[') && (!inBrackets)) { inBrackets = true; c = in.get();  if (in.eof()) { break; }  }
479                 else if ((c == ']') && (inBrackets)) { 
480                     inBrackets = false; 
481                     int temp;
482                     m->mothurConvert(num, temp);
483                     nums.push_back(temp);
484                     num = "";
485                     
486                     //save info to vectors
487                     if (matrixFormat == "dense") {
488                         
489                         //sanity check
490                         if (nums.size() != lookup.size()) { m->mothurOut("[ERROR]: trouble parsing OTU data.  OTU " + toString(otuCount) + " causing errors.\n"); m->control_pressed = true; }
491                         
492                         //set abundances for this otu
493                         //nums contains [abundSample0, abundSample1, abundSample2, ...] for current OTU
494                         for (int j = 0; j < lookup.size(); j++) { lookup[j]->set(otuCount, nums[j], groupNames[j]); }
495                         
496                         otuCount++;
497                     }else {
498                         //sanity check
499                         if (nums.size() != 3) { m->mothurOut("[ERROR]: trouble parsing OTU data.\n"); m->control_pressed = true; }
500                         
501                         //nums contains [otuNum, sampleNum, abundance]
502                         lookup[nums[1]]->set(nums[0], nums[2], groupNames[nums[1]]);
503                     }
504                     nums.clear();
505                 }
506                 
507                 if (inBrackets) {
508                     if (c == ',') {
509                         int temp;
510                         m->mothurConvert(num, temp);
511                         nums.push_back(temp);
512                         num = "";
513                     }else { if (!isspace(c)) { num += c; }  }
514                 }
515             }
516         }
517         
518         SharedUtil util;
519         
520                 bool remove = false;
521                 for (int i = 0; i < lookup.size(); i++) {
522                         //if this sharedrabund is not from a group the user wants then delete it.
523                         if (util.isValidGroup(lookup[i]->getGroup(), m->getGroups()) == false) { 
524                                 remove = true;
525                                 delete lookup[i]; lookup[i] = NULL;
526                                 lookup.erase(lookup.begin()+i); 
527                                 i--; 
528                         }
529                 }
530                 
531                 if (remove) { eliminateZeroOTUS(lookup); }
532
533         
534         return lookup;
535     }
536         catch(exception& e) {
537                 m->errorOut(e, "SharedCommand", "readData");
538                 exit(1);
539         }
540 }
541 //**********************************************************************************************************************
542 int SharedCommand::eliminateZeroOTUS(vector<SharedRAbundVector*>& thislookup) {
543     try {
544         
545         vector<SharedRAbundVector*> newLookup;
546         for (int i = 0; i < thislookup.size(); i++) {
547             SharedRAbundVector* temp = new SharedRAbundVector();
548             temp->setLabel(thislookup[i]->getLabel());
549             temp->setGroup(thislookup[i]->getGroup());
550             newLookup.push_back(temp);
551         }
552         
553         //for each bin
554         vector<string> newBinLabels;
555         string snumBins = toString(thislookup[0]->getNumBins());
556         for (int i = 0; i < thislookup[0]->getNumBins(); i++) {
557             if (m->control_pressed) { for (int j = 0; j < newLookup.size(); j++) {  delete newLookup[j];  } return 0; }
558             
559             //look at each sharedRabund and make sure they are not all zero
560             bool allZero = true;
561             for (int j = 0; j < thislookup.size(); j++) {
562                 if (thislookup[j]->getAbundance(i) != 0) { allZero = false;  break;  }
563             }
564             
565             //if they are not all zero add this bin
566             if (!allZero) {
567                 for (int j = 0; j < thislookup.size(); j++) {
568                     newLookup[j]->push_back(thislookup[j]->getAbundance(i), thislookup[j]->getGroup());
569                 }
570                 
571                 //if there is a bin label use it otherwise make one
572                 string binLabel = "Otu";
573                 string sbinNumber = toString(i+1);
574                 if (sbinNumber.length() < snumBins.length()) { 
575                     int diff = snumBins.length() - sbinNumber.length();
576                     for (int h = 0; h < diff; h++) { binLabel += "0"; }
577                 }
578                 binLabel += sbinNumber; 
579                 if (i < m->currentBinLabels.size()) {  binLabel = m->currentBinLabels[i]; }
580                 
581                 newBinLabels.push_back(binLabel);
582             }
583         }
584         
585         for (int j = 0; j < thislookup.size(); j++) {  delete thislookup[j];  }
586         
587         thislookup = newLookup;
588         m->currentBinLabels = newBinLabels;
589         
590         return 0;
591         
592     }
593     catch(exception& e) {
594         m->errorOut(e, "SharedCommand", "eliminateZeroOTUS");
595         exit(1);
596     }
597 }
598 //**********************************************************************************************************************
599 int SharedCommand::getDims(string line, int& shapeNumRows, int& shapeNumCols) {
600         try {
601         //get shape
602         bool inBar = false;
603         string num = "";
604         
605         for (int i = 0; i < line.length(); i++) {
606             
607             //you want to ignore any ; until you reach the next '
608             if ((line[i] == '[') && (!inBar)) {  inBar = true; i++;  if (!(i < line.length())) { break; } } 
609             else if ((line[i] == ']') && (inBar)) {  
610                 inBar= false;  
611                 m->mothurConvert(num, shapeNumCols);
612                 break;
613             } 
614             
615             if (inBar) {  
616                 if (line[i] == ',') {
617                     m->mothurConvert(num, shapeNumRows);
618                     num = "";
619                 }else { if (!isspace(line[i])) { num += line[i]; }  }
620             }
621         }
622         
623         return 0;
624     }
625         catch(exception& e) {
626                 m->errorOut(e, "SharedCommand", "getDims");
627                 exit(1);
628         }
629 }
630 //**********************************************************************************************************************
631 vector<string> SharedCommand::readRows(string line, ifstream& in, int& numRows) {
632         try {
633         /*"rows":[
634          {"id":"Otu01", "metadata":{"taxonomy":["Bacteria", "Bacteroidetes", "Bacteroidia", "Bacteroidales", "Porphyromonadaceae", "unclassified"], "bootstrap":[100, 100, 100, 100, 100, 100]}},
635          {"id":"Otu02", "metadata":{"taxonomy":["Bacteria", "Bacteroidetes", "Bacteroidia", "Bacteroidales", "Rikenellaceae", "Alistipes"], "bootstrap":[100, 100, 100, 100, 100, 100]}},
636          ...
637          ],*/
638         vector<string> names;
639         int countOpenBrace = 0;
640         int countClosedBrace = 0;
641         int openParen = 0;
642         int closeParen = 0;
643         string nextRow = "";
644         bool end = false;
645         
646         for (int i = 0; i < line.length(); i++) {
647             
648             if (m->control_pressed) { return names; }
649             
650             if (line[i] == '[')         { countOpenBrace++;     }
651             else if (line[i] == ']')    { countClosedBrace++;   }
652             else if (line[i] == '{')    { openParen++;          }
653             else if (line[i] == '}')    { closeParen++;         }
654             else if (openParen != 0)    { nextRow += line[i];   }  //you are reading the row info
655             
656             //you have reached the end of the rows info
657             if ((countOpenBrace == countClosedBrace) && (countClosedBrace != 0)) { end = true; break; }
658             if ((openParen == closeParen) && (closeParen != 0)) { //process row 
659                 numRows++;
660                 vector<string> items;
661                 m->splitAtChar(nextRow, items, ','); //parse by comma, will return junk for metadata but we aren't using that anyway
662                 string part = items[0]; items.clear();
663                 m->splitAtChar(part, items, ':'); //split part we want containing the ids
664                 string name = items[1];
665                 
666                 //remove "" if needed
667                 int pos = name.find("\"");
668                 if (pos != string::npos) {
669                     string newName = "";
670                     for (int k = 0; k < name.length(); k++) {
671                         if (name[k] != '\"') { newName += name[k]; }
672                     }
673                     name = newName;
674                 }
675                 names.push_back(name);
676                 nextRow = "";
677                 openParen = 0;
678                 closeParen = 0;
679             }
680         }
681         
682         //keep reading
683         if (!end) {
684             while (!in.eof()) {
685                 
686                 if (m->control_pressed) { break; }
687                 
688                 char c = in.get(); m->gobble(in);
689                 
690                 if (c == '[')               { countOpenBrace++;     }
691                 else if (c == ']')          { countClosedBrace++;   }
692                 else if (c == '{')          { openParen++;          }
693                 else if (c == '}')          { closeParen++;         }
694                 else if (openParen != 0)    { nextRow += c;         }  //you are reading the row info
695                 
696                 
697                 //you have reached the end of the rows info
698                 if ((countOpenBrace == countClosedBrace) && (countClosedBrace != 0)) { end = true; break; }
699                 if ((openParen == closeParen) && (closeParen != 0)) { //process row 
700                     numRows++;
701                     vector<string> items;
702                     m->splitAtChar(nextRow, items, ','); //parse by comma, will return junk for metadata but we aren't using that anyway
703                     string part = items[0]; items.clear();
704                     m->splitAtChar(part, items, ':'); //split part we want containing the ids
705                     string name = items[1];
706                     
707                     //remove "" if needed
708                     int pos = name.find("\"");
709                     if (pos != string::npos) {
710                         string newName = "";
711                         for (int k = 0; k < name.length(); k++) {
712                             if (name[k] != '\"') { newName += name[k]; }
713                         }
714                         name = newName;
715                     }
716                     names.push_back(name);
717                     nextRow = "";
718                     openParen = 0;
719                     closeParen = 0;
720                 }  
721             }
722         }
723         
724         return names;
725     }
726         catch(exception& e) {
727                 m->errorOut(e, "SharedCommand", "readRows");
728                 exit(1);
729         }
730 }
731 //**********************************************************************************************************************
732 //designed for things like "type": "OTU table", returns map type -> OTU table
733 string SharedCommand::getTag(string& line) {
734         try {
735         bool inQuotes = false;
736         string tag = "";
737         char c = '\"';
738         
739         for (int i = 0; i < line.length(); i++) {
740         
741             //you want to ignore any ; until you reach the next '
742                         if ((line[i] == c) && (!inQuotes)) {  inQuotes = true;  } 
743                         else if ((line[i] == c) && (inQuotes)) {  
744                 inQuotes= false;  
745                 line = line.substr(i+1);
746                 return tag;
747             } 
748             
749                         if (inQuotes) {  if (line[i] != c) { tag += line[i]; }  }
750         }
751         
752         return tag;
753     }
754         catch(exception& e) {
755                 m->errorOut(e, "SharedCommand", "getInfo");
756                 exit(1);
757         }
758 }
759 //**********************************************************************************************************************
760 int SharedCommand::createSharedFromListGroup(string filename) {
761         try {
762         ofstream out;
763         m->openOutputFile(filename, out);
764         
765         GroupMap* groupMap = new GroupMap(groupfile);
766         
767         int groupError = groupMap->readMap();
768         if (groupError == 1) { delete groupMap; return 0; }
769         vector<string> allGroups = groupMap->getNamesOfGroups();
770         m->setAllGroups(allGroups);
771         
772         pickedGroups = false;
773         
774         //if hte user has not specified any groups then use them all
775         if (Groups.size() == 0) {
776             Groups = groupMap->getNamesOfGroups(); m->setGroups(Groups);
777         }else { pickedGroups = true; }
778         
779         //fill filehandles with neccessary ofstreams
780         int i;
781         ofstream* temp;
782         for (i=0; i<Groups.size(); i++) {
783             temp = new ofstream;
784             filehandles[Groups[i]] = temp;
785         }
786         
787         //set fileroot
788         fileroot = outputDir + m->getRootName(m->getSimpleName(listfile));
789         
790         //clears file before we start to write to it below
791         for (int i=0; i<Groups.size(); i++) {
792             m->mothurRemove((fileroot + Groups[i] + "." + getOutputFileNameTag("rabund")));
793             outputNames.push_back((fileroot + Groups[i] + "." + getOutputFileNameTag("rabund")));
794             outputTypes["rabund"].push_back((fileroot + Groups[i] + "." + getOutputFileNameTag("rabund")));
795         }
796         
797         string errorOff = "no error";
798         
799         //if user provided an order file containing the order the shared file should be in read it
800         //if (ordergroupfile != "") { readOrderFile(); }
801         
802         InputData input(listfile, "shared");
803         SharedListVector* SharedList = input.getSharedListVector();
804         string lastLabel = SharedList->getLabel();
805         vector<SharedRAbundVector*> lookup; 
806         
807         if (m->control_pressed) { 
808             delete SharedList; delete groupMap; 
809             for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {  delete it3->second;  }
810             out.close(); m->mothurRemove(filename); 
811             for (int i=0; i<Groups.size(); i++) {  m->mothurRemove((fileroot + Groups[i] + "." + getOutputFileNameTag("rabund")));              }
812             return 0; 
813         }
814         
815         //sanity check
816         vector<string> groupMapNamesSeqs = groupMap->getNamesSeqs();
817         int error = ListGroupSameSeqs(groupMapNamesSeqs, SharedList);
818         
819         if ((!pickedGroups) && (SharedList->getNumSeqs() != groupMap->getNumSeqs())) {  //if the user has not specified any groups and their files don't match exit with error
820             m->mothurOut("Your group file contains " + toString(groupMap->getNumSeqs()) + " sequences and list file contains " + toString(SharedList->getNumSeqs()) + " sequences. Please correct."); m->mothurOutEndLine(); 
821             
822             out.close();
823             m->mothurRemove(filename); //remove blank shared file you made
824             
825             createMisMatchFile(SharedList, groupMap);
826             
827             //delete memory
828             for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {
829                 delete it3->second;
830             }
831             
832             delete SharedList; delete groupMap; 
833             
834             return 0; 
835         }
836         
837         if (error == 1) { m->control_pressed = true; }
838         
839         //if user has specified groups make new groupfile for them
840         if (pickedGroups) { //make new group file
841             string groups = "";
842             if (m->getNumGroups() < 4) {
843                 for (int i = 0; i < m->getNumGroups(); i++) {
844                     groups += (m->getGroups())[i] + ".";
845                 }
846             }else { groups = "merge"; }
847             
848             string newGroupFile = outputDir + m->getRootName(m->getSimpleName(listfile)) + groups + getOutputFileNameTag("group");
849             outputTypes["group"].push_back(newGroupFile); 
850             outputNames.push_back(newGroupFile);
851             ofstream outGroups;
852             m->openOutputFile(newGroupFile, outGroups);
853             
854             vector<string> names = groupMap->getNamesSeqs();
855             string groupName;
856             for (int i = 0; i < names.size(); i++) {
857                 groupName = groupMap->getGroup(names[i]);
858                 if (isValidGroup(groupName, m->getGroups())) {
859                     outGroups << names[i] << '\t' << groupName << endl;
860                 }
861             }
862             outGroups.close();
863         }
864         
865         //if the users enters label "0.06" and there is no "0.06" in their file use the next lowest label.
866         set<string> processedLabels;
867         set<string> userLabels = labels;        
868         
869         while((SharedList != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
870             if (m->control_pressed) { 
871                 delete SharedList; delete groupMap;
872                 for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {  delete it3->second;  }
873                 out.close(); m->mothurRemove(filename); 
874                 for (int i=0; i<Groups.size(); i++) {  m->mothurRemove((fileroot + Groups[i] + "." + getOutputFileNameTag("rabund")));          }
875                 return 0; 
876             }
877             
878             if(allLines == 1 || labels.count(SharedList->getLabel()) == 1){
879                 
880                 lookup = SharedList->getSharedRAbundVector();
881                 
882                 m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
883                 if (pickedGroups) { //check for otus with no seqs in them
884                     eliminateZeroOTUS(lookup);
885                 }
886                 
887                 if (m->control_pressed) { 
888                     delete SharedList; delete groupMap; 
889                     for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }
890                     for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {  delete it3->second;  }
891                     out.close(); m->mothurRemove(filename); 
892                     for (int i=0; i<Groups.size(); i++) {  m->mothurRemove((fileroot + Groups[i] + "." + getOutputFileNameTag("rabund")));              }
893                     return 0; 
894                 }
895                 
896                 if (!m->printedHeaders) { lookup[0]->printHeaders(out); }
897                 printSharedData(lookup, out); //prints info to the .shared file
898                 for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }
899                 
900                 processedLabels.insert(SharedList->getLabel());
901                 userLabels.erase(SharedList->getLabel());
902             }
903             
904             if ((m->anyLabelsToProcess(SharedList->getLabel(), userLabels, errorOff) == true) && (processedLabels.count(lastLabel) != 1)) {
905                 string saveLabel = SharedList->getLabel();
906                 
907                 delete SharedList;
908                 SharedList = input.getSharedListVector(lastLabel); //get new list vector to process
909                 
910                 lookup = SharedList->getSharedRAbundVector();
911                 m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
912                 if (pickedGroups) { //check for otus with no seqs in them
913                     eliminateZeroOTUS(lookup);
914                 }
915                 
916                 
917                 if (m->control_pressed) { 
918                     delete SharedList; delete groupMap; 
919                     for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }
920                     for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {  delete it3->second;  }
921                     out.close(); m->mothurRemove(filename); 
922                     for (int i=0; i<Groups.size(); i++) {  m->mothurRemove((fileroot + Groups[i] + "." + getOutputFileNameTag("rabund")));              }
923                     return 0; 
924                 }
925                 
926                 if (!m->printedHeaders) { lookup[0]->printHeaders(out); }
927                 printSharedData(lookup, out); //prints info to the .shared file
928                 for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }
929                 
930                 processedLabels.insert(SharedList->getLabel());
931                 userLabels.erase(SharedList->getLabel());
932                 
933                 //restore real lastlabel to save below
934                 SharedList->setLabel(saveLabel);
935             }
936             
937             
938             lastLabel = SharedList->getLabel();
939             
940             delete SharedList;
941             SharedList = input.getSharedListVector(); //get new list vector to process
942         }
943         
944         //output error messages about any remaining user labels
945         set<string>::iterator it;
946         bool needToRun = false;
947         for (it = userLabels.begin(); it != userLabels.end(); it++) {  
948             if (processedLabels.count(lastLabel) != 1) {
949                 needToRun = true;
950             }
951         }
952         
953         //run last label if you need to
954         if (needToRun == true)  {
955             if (SharedList != NULL) {   delete SharedList;      }
956             SharedList = input.getSharedListVector(lastLabel); //get new list vector to process
957             
958             lookup = SharedList->getSharedRAbundVector();
959             m->mothurOut(lookup[0]->getLabel()); m->mothurOutEndLine();
960             if (pickedGroups) { //check for otus with no seqs in them
961                 eliminateZeroOTUS(lookup);
962             }
963             
964             if (m->control_pressed) { 
965                 delete groupMap;
966                 for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {  delete it3->second;   }
967                 out.close(); m->mothurRemove(filename); 
968                 for (int i=0; i<Groups.size(); i++) {  m->mothurRemove((fileroot + Groups[i] + "." + getOutputFileNameTag("rabund")));          }
969                 return 0; 
970             }
971             
972             if (!m->printedHeaders) { lookup[0]->printHeaders(out); }
973             printSharedData(lookup, out); //prints info to the .shared file
974             for (int i = 0; i < lookup.size(); i++) {  delete lookup[i];  }
975             delete SharedList;
976         }
977         
978         out.close();
979         
980         for (it3 = filehandles.begin(); it3 != filehandles.end(); it3++) {
981             delete it3->second;
982         }
983         
984         delete groupMap;
985                 
986         if (m->control_pressed) { 
987             m->mothurRemove(filename); 
988             for (int i=0; i<Groups.size(); i++) {  m->mothurRemove((fileroot + Groups[i] + "." + getOutputFileNameTag("rabund")));              }
989             return 0; 
990         }
991
992         return 0;
993     }
994         catch(exception& e) {
995                 m->errorOut(e, "SharedCommand", "createSharedFromListGroup");
996                 exit(1);
997         }
998 }
999 //**********************************************************************************************************************
1000 void SharedCommand::printSharedData(vector<SharedRAbundVector*> thislookup, ofstream& out) {
1001         try {
1002                 
1003                 if (order.size() == 0) { //user has not specified an order so do aplabetically
1004                         sort(thislookup.begin(), thislookup.end(), compareSharedRabunds);
1005                         
1006                         m->clearGroups();
1007                         vector<string> Groups;
1008                         
1009                         //initialize bin values
1010                         for (int i = 0; i < thislookup.size(); i++) {
1011                                 out << thislookup[i]->getLabel() << '\t' << thislookup[i]->getGroup() << '\t';
1012                                 thislookup[i]->print(out);
1013                                 
1014                                 Groups.push_back(thislookup[i]->getGroup());
1015                                 
1016                                 RAbundVector rav = thislookup[i]->getRAbundVector();
1017                                 m->openOutputFileAppend(fileroot + thislookup[i]->getGroup() + "." + getOutputFileNameTag("rabund"), *(filehandles[thislookup[i]->getGroup()]));
1018                                 rav.print(*(filehandles[thislookup[i]->getGroup()]));
1019                                 (*(filehandles[thislookup[i]->getGroup()])).close();
1020                         }
1021                         m->setGroups(Groups);
1022                 }else{
1023                         //create a map from groupName to each sharedrabund
1024                         map<string, SharedRAbundVector*> myMap;
1025                         map<string, SharedRAbundVector*>::iterator myIt;
1026                         
1027                         for (int i = 0; i < thislookup.size(); i++) {
1028                                 myMap[thislookup[i]->getGroup()] = thislookup[i];
1029                         }
1030                         
1031                         m->clearGroups();
1032                         vector<string> Groups;
1033                         
1034                         //loop through ordered list and print the rabund
1035                         for (int i = 0; i < order.size(); i++) {
1036                                 myIt = myMap.find(order[i]);
1037                                 
1038                                 if(myIt != myMap.end()) { //we found it
1039                                         out << (myIt->second)->getLabel() << '\t' << (myIt->second)->getGroup() << '\t';
1040                                         (myIt->second)->print(out);
1041                                         
1042                                         Groups.push_back((myIt->second)->getGroup());
1043                                 
1044                                         RAbundVector rav = (myIt->second)->getRAbundVector();
1045                                         m->openOutputFileAppend(fileroot + (myIt->second)->getGroup() + "." + getOutputFileNameTag("rabund"), *(filehandles[(myIt->second)->getGroup()]));
1046                                         rav.print(*(filehandles[(myIt->second)->getGroup()]));
1047                                         (*(filehandles[(myIt->second)->getGroup()])).close();
1048                                 }else{
1049                                         m->mothurOut("Can't find shared info for " + order[i] + ", skipping."); m->mothurOutEndLine();
1050                                 }
1051                         }
1052                         
1053                         m->setGroups(Groups);
1054                 
1055                 }
1056  
1057         }
1058         catch(exception& e) {
1059                 m->errorOut(e, "SharedCommand", "printSharedData");
1060                 exit(1);
1061         }
1062 }
1063 //**********************************************************************************************************************
1064 int SharedCommand::createMisMatchFile(SharedListVector* SharedList, GroupMap* groupMap) {
1065         try {
1066                 ofstream outMisMatch;
1067                 string outputMisMatchName = outputDir + m->getRootName(m->getSimpleName(listfile));
1068                 
1069                 //you have sequences in your list file that are not in your group file
1070                 if (SharedList->getNumSeqs() > groupMap->getNumSeqs()) { 
1071                         outputMisMatchName += "missing.group";
1072                         m->mothurOut("For a list of names that are in your list file and not in your group file, please refer to " + outputMisMatchName + "."); m->mothurOutEndLine();
1073                         
1074                         m->openOutputFile(outputMisMatchName, outMisMatch);
1075                         
1076                         set<string> listNames;
1077                         set<string>::iterator itList;
1078                         
1079                         //go through list and if group returns "not found" output it
1080                         for (int i = 0; i < SharedList->getNumBins(); i++) {
1081                                 if (m->control_pressed) { outMisMatch.close(); m->mothurRemove(outputMisMatchName); return 0; } 
1082                         
1083                                 string names = SharedList->get(i); 
1084                                 
1085                 vector<string> binNames;
1086                 m->splitAtComma(names, binNames);
1087                 
1088                                 for (int j = 0; j < binNames.size(); j++) { 
1089                                         string name = binNames[j];
1090                                         string group = groupMap->getGroup(name);
1091                                         
1092                                         if(group == "not found") {      outMisMatch << name << endl;  }
1093                                         
1094                                         itList = listNames.find(name);
1095                                         if (itList != listNames.end()) {  m->mothurOut(name + " is in your list file more than once.  Sequence names must be unique. please correct."); m->mothurOutEndLine(); }
1096                                         else { listNames.insert(name); }
1097                                 }
1098                         }
1099                         
1100                         outMisMatch.close();
1101                         
1102                 
1103                 }else {//you have sequences in your group file that are not in you list file
1104                         
1105                         outputMisMatchName += "missing.name";
1106                         m->mothurOut("For a list of names that are in your group file and not in your list file, please refer to " + outputMisMatchName + "."); m->mothurOutEndLine();
1107                         
1108                         map<string, string> namesInList;
1109                         map<string, string>::iterator itList;
1110                         
1111                         //go through listfile and get names
1112                         for (int i = 0; i < SharedList->getNumBins(); i++) {
1113                                 if (m->control_pressed) {  return 0; } 
1114
1115                                 
1116                                 string names = SharedList->get(i); 
1117                 
1118                                 vector<string> binNames;
1119                 m->splitAtComma(names, binNames);
1120                 
1121                                 for (int j = 0; j < binNames.size(); j++) { 
1122
1123                                         string name = binNames[j];
1124                                         
1125                                         itList = namesInList.find(name);
1126                                         if (itList != namesInList.end()) {  m->mothurOut(name + " is in your list file more than once.  Sequence names must be unique. please correct."); m->mothurOutEndLine(); }
1127
1128                                         namesInList[name] = name;
1129                                         
1130                                 }
1131                         }
1132                         
1133                         //get names of sequences in groupfile
1134                         vector<string> seqNames = groupMap->getNamesSeqs();
1135                 
1136                         map<string, string>::iterator itMatch;
1137                         
1138                         m->openOutputFile(outputMisMatchName, outMisMatch);
1139                         
1140                         //loop through names in seqNames and if they aren't in namesIn list output them
1141                         for (int i = 0; i < seqNames.size(); i++) {
1142                                 if (m->control_pressed) { outMisMatch.close(); m->mothurRemove(outputMisMatchName); return 0; } 
1143                                 
1144                                 itMatch = namesInList.find(seqNames[i]);
1145                                 
1146                                 if (itMatch == namesInList.end()) {
1147                                 
1148                                         outMisMatch << seqNames[i] << endl; 
1149                                 }
1150                         }               
1151                         outMisMatch.close();
1152                 }
1153                 
1154                 return 0;
1155         }
1156         catch(exception& e) {
1157                 m->errorOut(e, "SharedCommand", "createMisMatchFile");
1158                 exit(1);
1159         }
1160 }
1161 //**********************************************************************************************************************
1162 int SharedCommand::ListGroupSameSeqs(vector<string>& groupMapsSeqs, SharedListVector* SharedList) {
1163         try {
1164                 int error = 0; 
1165         
1166                 set<string> groupNamesSeqs;
1167                 for(int i = 0; i < groupMapsSeqs.size(); i++) {
1168                         groupNamesSeqs.insert(groupMapsSeqs[i]);
1169                 }
1170                 
1171                 //go through list and if group returns "not found" output it
1172                 for (int i = 0; i < SharedList->getNumBins(); i++) {
1173                         if (m->control_pressed) { return 0; } 
1174                         
1175                         string names = SharedList->get(i); 
1176                         
1177                         vector<string> listNames;
1178                         m->splitAtComma(names, listNames);
1179                         
1180                         for (int j = 0; j < listNames.size(); j++) {
1181                                 int num = groupNamesSeqs.count(listNames[j]);
1182                                 
1183                                 if (num == 0) { error = 1; m->mothurOut("[ERROR]: " + listNames[j] + " is in your listfile and not in your groupfile. Please correct."); m->mothurOutEndLine(); }
1184                                 else { groupNamesSeqs.erase(listNames[j]); }
1185                         }
1186                 }
1187                 
1188                 for (set<string>::iterator itGroupSet = groupNamesSeqs.begin(); itGroupSet != groupNamesSeqs.end(); itGroupSet++) {
1189                         error = 1; 
1190                         m->mothurOut("[ERROR]: " + (*itGroupSet) + " is in your groupfile and not your listfile. Please correct."); m->mothurOutEndLine();
1191                 }
1192                                 
1193                 return error;
1194         }
1195         catch(exception& e) {
1196                 m->errorOut(e, "SharedCommand", "ListGroupSameSeqs");
1197                 exit(1);
1198         }
1199 }
1200 //**********************************************************************************************************************
1201
1202 SharedCommand::~SharedCommand(){
1203         //delete list;
1204         
1205         
1206 }
1207 //**********************************************************************************************************************
1208 int SharedCommand::readOrderFile() {
1209         try {
1210                 //remove old names
1211                 order.clear();
1212                 
1213                 ifstream in;
1214                 m->openInputFile(ordergroupfile, in);
1215                 string thisGroup;
1216                 
1217                 while(!in.eof()){
1218                         in >> thisGroup; m->gobble(in);
1219                                                 
1220                         order.push_back(thisGroup);
1221                         
1222                         if (m->control_pressed) { order.clear(); break; }
1223                 }
1224                 in.close();             
1225                 
1226                 return 0;
1227         }
1228         catch(exception& e) {
1229                 m->errorOut(e, "SharedCommand", "readOrderFile");
1230                 exit(1);
1231         }
1232 }
1233 //**********************************************************************************************************************
1234
1235 bool SharedCommand::isValidGroup(string groupname, vector<string> groups) {
1236         try {
1237                 for (int i = 0; i < groups.size(); i++) {
1238                         if (groupname == groups[i]) { return true; }
1239                 }
1240                 
1241                 return false;
1242         }
1243         catch(exception& e) {
1244                 m->errorOut(e, "SharedCommand", "isValidGroup");
1245                 exit(1);
1246         }
1247 }
1248 /************************************************************/
1249
1250