]> git.donarmstrong.com Git - mothur.git/blob - chimerauchimecommand.cpp
rewrote metastats command in c++, added mothurRemove function to handle ~ error....
[mothur.git] / chimerauchimecommand.cpp
1 /*
2  *  chimerauchimecommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 5/13/11.
6  *  Copyright 2011 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "chimerauchimecommand.h"
11 #include "deconvolutecommand.h"
12 #include "uc.h"
13 #include "sequence.hpp"
14 #include "referencedb.h"
15
16
17 //**********************************************************************************************************************
18 vector<string> ChimeraUchimeCommand::setParameters(){   
19         try {
20                 CommandParameter ptemplate("reference", "InputTypes", "", "", "none", "none", "none",false,true); parameters.push_back(ptemplate);
21                 CommandParameter pfasta("fasta", "InputTypes", "", "", "none", "none", "none",false,true); parameters.push_back(pfasta);
22                 CommandParameter pname("name", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(pname);
23                 CommandParameter pprocessors("processors", "Number", "", "1", "", "", "",false,false); parameters.push_back(pprocessors);
24                 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "",false,false); parameters.push_back(pinputdir);
25                 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "",false,false); parameters.push_back(poutputdir);
26                 CommandParameter pabskew("abskew", "Number", "", "1.9", "", "", "",false,false); parameters.push_back(pabskew);
27                 CommandParameter pchimealns("chimealns", "Boolean", "", "F", "", "", "",false,false); parameters.push_back(pchimealns);
28                 CommandParameter pminh("minh", "Number", "", "0.3", "", "", "",false,false); parameters.push_back(pminh);
29                 CommandParameter pmindiv("mindiv", "Number", "", "0.5", "", "", "",false,false); parameters.push_back(pmindiv);
30                 CommandParameter pxn("xn", "Number", "", "8.0", "", "", "",false,false); parameters.push_back(pxn);
31                 CommandParameter pdn("dn", "Number", "", "1.4", "", "", "",false,false); parameters.push_back(pdn);
32                 CommandParameter pxa("xa", "Number", "", "1", "", "", "",false,false); parameters.push_back(pxa);
33                 CommandParameter pchunks("chunks", "Number", "", "4", "", "", "",false,false); parameters.push_back(pchunks);
34                 CommandParameter pminchunk("minchunk", "Number", "", "64", "", "", "",false,false); parameters.push_back(pminchunk);
35                 CommandParameter pidsmoothwindow("idsmoothwindow", "Number", "", "32", "", "", "",false,false); parameters.push_back(pidsmoothwindow);
36                 //CommandParameter pminsmoothid("minsmoothid", "Number", "", "0.95", "", "", "",false,false); parameters.push_back(pminsmoothid);
37                 CommandParameter pmaxp("maxp", "Number", "", "2", "", "", "",false,false); parameters.push_back(pmaxp);
38                 CommandParameter pskipgaps("skipgaps", "Boolean", "", "T", "", "", "",false,false); parameters.push_back(pskipgaps);
39                 CommandParameter pskipgaps2("skipgaps2", "Boolean", "", "T", "", "", "",false,false); parameters.push_back(pskipgaps2);
40                 CommandParameter pminlen("minlen", "Number", "", "10", "", "", "",false,false); parameters.push_back(pminlen);
41                 CommandParameter pmaxlen("maxlen", "Number", "", "10000", "", "", "",false,false); parameters.push_back(pmaxlen);
42                 CommandParameter pucl("ucl", "Boolean", "", "F", "", "", "",false,false); parameters.push_back(pucl);
43                 CommandParameter pqueryfract("queryfract", "Number", "", "0.5", "", "", "",false,false); parameters.push_back(pqueryfract);
44
45                 vector<string> myArray;
46                 for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
47                 return myArray;
48         }
49         catch(exception& e) {
50                 m->errorOut(e, "ChimeraUchimeCommand", "setParameters");
51                 exit(1);
52         }
53 }
54 //**********************************************************************************************************************
55 string ChimeraUchimeCommand::getHelpString(){   
56         try {
57                 string helpString = "";
58                 helpString += "The chimera.uchime command reads a fastafile and referencefile and outputs potentially chimeric sequences.\n";
59                 helpString += "This command is a wrapper for uchime written by Robert C. Edgar.\n";
60                 helpString += "The chimera.uchime command parameters are fasta, name, reference, processors, abskew, chimealns, minh, mindiv, xn, dn, xa, chunks, minchunk, idsmoothwindow, minsmoothid, maxp, skipgaps, skipgaps2, minlen, maxlen, ucl and queryfact.\n";
61                 helpString += "The fasta parameter allows you to enter the fasta file containing your potentially chimeric sequences, and is required, unless you have a valid current fasta file. \n";
62                 helpString += "The name parameter allows you to provide a name file, if you are using template=self. \n";
63                 helpString += "You may enter multiple fasta files by separating their names with dashes. ie. fasta=abrecovery.fasta-amazon.fasta \n";
64                 helpString += "The reference parameter allows you to enter a reference file containing known non-chimeric sequences, and is required. You may also set template=self, in this case the abundant sequences will be used as potential parents. \n";
65                 helpString += "The processors parameter allows you to specify how many processors you would like to use.  The default is 1. \n";
66                 helpString += "The abskew parameter can only be used with template=self. Minimum abundance skew. Default 1.9. Abundance skew is: min [ abund(parent1), abund(parent2) ] / abund(query).\n";
67                 helpString += "The chimealns parameter allows you to indicate you would like a file containing multiple alignments of query sequences to parents in human readable format. Alignments show columns with differences that support or contradict a chimeric model.\n";
68                 helpString += "The minh parameter - mininum score to report chimera. Default 0.3. Values from 0.1 to 5 might be reasonable. Lower values increase sensitivity but may report more false positives. If you decrease xn you may need to increase minh, and vice versa.\n";
69                 helpString += "The mindiv parameter - minimum divergence ratio, default 0.5. Div ratio is 100%% - %%identity between query sequence and the closest candidate for being a parent. If you don't care about very close chimeras, then you could increase mindiv to, say, 1.0 or 2.0, and also decrease minh, say to 0.1, to increase sensitivity. How well this works will depend on your data. Best is to tune parameters on a good benchmark.\n";
70                 helpString += "The xn parameter - weight of a no vote. Default 8.0. Decreasing this weight to around 3 or 4 may give better performance on denoised data.\n";
71                 helpString += "The dn parameter - pseudo-count prior on number of no votes. Default 1.4. Probably no good reason to change this unless you can retune to a good benchmark for your data. Reasonable values are probably in the range from 0.2 to 2.\n";
72                 helpString += "The xa parameter - weight of an abstain vote. Default 1. So far, results do not seem to be very sensitive to this parameter, but if you have a good training set might be worth trying. Reasonable values might range from 0.1 to 2.\n";
73                 helpString += "The chunks parameter is the number of chunks to extract from the query sequence when searching for parents. Default 4.\n";
74                 helpString += "The minchunk parameter is the minimum length of a chunk. Default 64.\n";
75                 helpString += "The idsmoothwindow parameter is the length of id smoothing window. Default 32.\n";
76                 //helpString += "The minsmoothid parameter - minimum factional identity over smoothed window of candidate parent. Default 0.95.\n";
77                 helpString += "The maxp parameter - maximum number of candidate parents to consider. Default 2. In tests so far, increasing maxp gives only a very small improvement in sensivity but tends to increase the error rate quite a bit.\n";
78                 helpString += "The skipgaps parameter controls how gapped columns affect counting of diffs. If skipgaps is set to T, columns containing gaps do not found as diffs. Default = T.\n";
79                 helpString += "The skipgaps2 parameter controls how gapped columns affect counting of diffs. If skipgaps2 is set to T, if column is immediately adjacent to a column containing a gap, it is not counted as a diff. Default = T.\n";
80                 helpString += "The minlen parameter is the minimum unaligned sequence length. Defaults 10. Applies to both query and reference sequences.\n";
81                 helpString += "The maxlen parameter is the maximum unaligned sequence length. Defaults 10000. Applies to both query and reference sequences.\n";
82                 helpString += "The ucl parameter - use local-X alignments. Default is global-X or false. On tests so far, global-X is always better; this option is retained because it just might work well on some future type of data.\n";
83                 helpString += "The queryfract parameter - minimum fraction of the query sequence that must be covered by a local-X alignment. Default 0.5. Applies only when ucl is true.\n";
84 #ifdef USE_MPI
85                 helpString += "When using MPI, the processors parameter is set to the number of MPI processes running. \n";
86 #endif
87                 helpString += "The chimera.uchime command should be in the following format: \n";
88                 helpString += "chimera.uchime(fasta=yourFastaFile, reference=yourTemplate) \n";
89                 helpString += "Example: chimera.uchime(fasta=AD.align, reference=silva.gold.align) \n";
90                 helpString += "Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFastaFile).\n";       
91                 return helpString;
92         }
93         catch(exception& e) {
94                 m->errorOut(e, "ChimeraUchimeCommand", "getHelpString");
95                 exit(1);
96         }
97 }
98 //**********************************************************************************************************************
99 ChimeraUchimeCommand::ChimeraUchimeCommand(){   
100         try {
101                 abort = true; calledHelp = true;
102                 setParameters();
103                 vector<string> tempOutNames;
104                 outputTypes["chimera"] = tempOutNames;
105                 outputTypes["accnos"] = tempOutNames;
106                 outputTypes["alns"] = tempOutNames;
107         }
108         catch(exception& e) {
109                 m->errorOut(e, "ChimeraUchimeCommand", "ChimeraUchimeCommand");
110                 exit(1);
111         }
112 }
113 //***************************************************************************************************************
114 ChimeraUchimeCommand::ChimeraUchimeCommand(string option)  {
115         try {
116                 abort = false; calledHelp = false; 
117                 ReferenceDB* rdb = ReferenceDB::getInstance();
118                 
119                 //allow user to run help
120                 if(option == "help") { help(); abort = true; calledHelp = true; }
121                 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
122                 
123                 else {
124                         vector<string> myArray = setParameters();
125                         
126                         OptionParser parser(option);
127                         map<string,string> parameters = parser.getParameters();
128                         
129                         ValidParameters validParameter("chimera.uchime");
130                         map<string,string>::iterator it;
131                         
132                         //check to make sure all parameters are valid for command
133                         for (it = parameters.begin(); it != parameters.end(); it++) { 
134                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
135                         }
136                         
137                         vector<string> tempOutNames;
138                         outputTypes["chimera"] = tempOutNames;
139                         outputTypes["accnos"] = tempOutNames;
140                         outputTypes["alns"] = tempOutNames;
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                         
146                         //check for required parameters
147                         fastafile = validParameter.validFile(parameters, "fasta", false);
148                         if (fastafile == "not found") {                                 
149                                 //if there is a current fasta file, use it
150                                 string filename = m->getFastaFile(); 
151                                 if (filename != "") { fastaFileNames.push_back(filename); m->mothurOut("Using " + filename + " as input file for the fasta parameter."); m->mothurOutEndLine(); }
152                                 else {  m->mothurOut("You have no current fastafile and the fasta parameter is required."); m->mothurOutEndLine(); abort = true; }
153                         }else { 
154                                 m->splitAtDash(fastafile, fastaFileNames);
155                                 
156                                 //go through files and make sure they are good, if not, then disregard them
157                                 for (int i = 0; i < fastaFileNames.size(); i++) {
158                                         
159                                         bool ignore = false;
160                                         if (fastaFileNames[i] == "current") { 
161                                                 fastaFileNames[i] = m->getFastaFile(); 
162                                                 if (fastaFileNames[i] != "") {  m->mothurOut("Using " + fastaFileNames[i] + " as input file for the fasta parameter where you had given current."); m->mothurOutEndLine(); }
163                                                 else {  
164                                                         m->mothurOut("You have no current fastafile, ignoring current."); m->mothurOutEndLine(); ignore=true; 
165                                                         //erase from file list
166                                                         fastaFileNames.erase(fastaFileNames.begin()+i);
167                                                         i--;
168                                                 }
169                                         }
170                                         
171                                         if (!ignore) {
172                                                 
173                                                 if (inputDir != "") {
174                                                         string path = m->hasPath(fastaFileNames[i]);
175                                                         //if the user has not given a path then, add inputdir. else leave path alone.
176                                                         if (path == "") {       fastaFileNames[i] = inputDir + fastaFileNames[i];               }
177                                                 }
178                                                 
179                                                 int ableToOpen;
180                                                 ifstream in;
181                                                 
182                                                 ableToOpen = m->openInputFile(fastaFileNames[i], in, "noerror");
183                                                 
184                                                 //if you can't open it, try default location
185                                                 if (ableToOpen == 1) {
186                                                         if (m->getDefaultPath() != "") { //default path is set
187                                                                 string tryPath = m->getDefaultPath() + m->getSimpleName(fastaFileNames[i]);
188                                                                 m->mothurOut("Unable to open " + fastaFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
189                                                                 ifstream in2;
190                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
191                                                                 in2.close();
192                                                                 fastaFileNames[i] = tryPath;
193                                                         }
194                                                 }
195                                                 
196                                                 if (ableToOpen == 1) {
197                                                         if (m->getOutputDir() != "") { //default path is set
198                                                                 string tryPath = m->getOutputDir() + m->getSimpleName(fastaFileNames[i]);
199                                                                 m->mothurOut("Unable to open " + fastaFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
200                                                                 ifstream in2;
201                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
202                                                                 in2.close();
203                                                                 fastaFileNames[i] = tryPath;
204                                                         }
205                                                 }
206                                                 
207                                                 in.close();
208                                                 
209                                                 if (ableToOpen == 1) { 
210                                                         m->mothurOut("Unable to open " + fastaFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine(); 
211                                                         //erase from file list
212                                                         fastaFileNames.erase(fastaFileNames.begin()+i);
213                                                         i--;
214                                                 }else {
215                                                         m->setFastaFile(fastaFileNames[i]);
216                                                 }
217                                         }
218                                 }
219                                 
220                                 //make sure there is at least one valid file left
221                                 if (fastaFileNames.size() == 0) { m->mothurOut("[ERROR]: no valid files."); m->mothurOutEndLine(); abort = true; }
222                         }
223                         
224                         
225                         //check for required parameters
226                         bool hasName = true;
227                         namefile = validParameter.validFile(parameters, "name", false);
228                         if (namefile == "not found") { namefile = "";  hasName = false; }
229                         else { 
230                                 m->splitAtDash(namefile, nameFileNames);
231                                 
232                                 //go through files and make sure they are good, if not, then disregard them
233                                 for (int i = 0; i < nameFileNames.size(); i++) {
234                                         
235                                         bool ignore = false;
236                                         if (nameFileNames[i] == "current") { 
237                                                 nameFileNames[i] = m->getNameFile(); 
238                                                 if (nameFileNames[i] != "") {  m->mothurOut("Using " + nameFileNames[i] + " as input file for the name parameter where you had given current."); m->mothurOutEndLine(); }
239                                                 else {  
240                                                         m->mothurOut("You have no current namefile, ignoring current."); m->mothurOutEndLine(); ignore=true; 
241                                                         //erase from file list
242                                                         nameFileNames.erase(nameFileNames.begin()+i);
243                                                         i--;
244                                                 }
245                                         }
246                                         
247                                         if (!ignore) {
248                                                 
249                                                 if (inputDir != "") {
250                                                         string path = m->hasPath(nameFileNames[i]);
251                                                         //if the user has not given a path then, add inputdir. else leave path alone.
252                                                         if (path == "") {       nameFileNames[i] = inputDir + nameFileNames[i];         }
253                                                 }
254                                                 
255                                                 int ableToOpen;
256                                                 ifstream in;
257                                                 
258                                                 ableToOpen = m->openInputFile(nameFileNames[i], in, "noerror");
259                                                 
260                                                 //if you can't open it, try default location
261                                                 if (ableToOpen == 1) {
262                                                         if (m->getDefaultPath() != "") { //default path is set
263                                                                 string tryPath = m->getDefaultPath() + m->getSimpleName(nameFileNames[i]);
264                                                                 m->mothurOut("Unable to open " + nameFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
265                                                                 ifstream in2;
266                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
267                                                                 in2.close();
268                                                                 nameFileNames[i] = tryPath;
269                                                         }
270                                                 }
271                                                 
272                                                 if (ableToOpen == 1) {
273                                                         if (m->getOutputDir() != "") { //default path is set
274                                                                 string tryPath = m->getOutputDir() + m->getSimpleName(nameFileNames[i]);
275                                                                 m->mothurOut("Unable to open " + nameFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
276                                                                 ifstream in2;
277                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
278                                                                 in2.close();
279                                                                 nameFileNames[i] = tryPath;
280                                                         }
281                                                 }
282                                                 
283                                                 in.close();
284                                                 
285                                                 if (ableToOpen == 1) { 
286                                                         m->mothurOut("Unable to open " + nameFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine(); 
287                                                         //erase from file list
288                                                         nameFileNames.erase(nameFileNames.begin()+i);
289                                                         i--;
290                                                 }else {
291                                                         m->setNameFile(nameFileNames[i]);
292                                                 }
293                                         }
294                                 }
295                                 
296                                 //make sure there is at least one valid file left
297                                 if (nameFileNames.size() == 0) { m->mothurOut("[ERROR]: no valid name files."); m->mothurOutEndLine(); abort = true; }
298                         }
299                         
300                         if (hasName && (nameFileNames.size() != fastaFileNames.size())) { m->mothurOut("[ERROR]: The number of namefiles does not match the number of fastafiles, please correct."); m->mothurOutEndLine(); abort=true; }
301                         
302                         //if the user changes the output directory command factory will send this info to us in the output parameter 
303                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = ""; }
304                         
305                         string path;
306                         it = parameters.find("reference");
307                         //user has given a template file
308                         if(it != parameters.end()){ 
309                                 if (it->second == "self") { templatefile = "self"; }
310                                 else {
311                                         path = m->hasPath(it->second);
312                                         //if the user has not given a path then, add inputdir. else leave path alone.
313                                         if (path == "") {       parameters["reference"] = inputDir + it->second;                }
314                                         
315                                         templatefile = validParameter.validFile(parameters, "reference", true);
316                                         if (templatefile == "not open") { abort = true; }
317                                         else if (templatefile == "not found") { //check for saved reference sequences
318                                                 if (rdb->getSavedReference() != "") {
319                                                         templatefile = rdb->getSavedReference();
320                                                         m->mothurOutEndLine();  m->mothurOut("Using sequences from " + rdb->getSavedReference() + "."); m->mothurOutEndLine();
321                                                 }else {
322                                                         m->mothurOut("[ERROR]: You don't have any saved reference sequences and the reference parameter is a required."); 
323                                                         m->mothurOutEndLine();
324                                                         abort = true; 
325                                                 }
326                                         }
327                                 }
328                         }else if (hasName) {  templatefile = "self"; }
329                         else { 
330                                 if (rdb->getSavedReference() != "") {
331                                         templatefile = rdb->getSavedReference();
332                                         m->mothurOutEndLine();  m->mothurOut("Using sequences from " + rdb->getSavedReference() + "."); m->mothurOutEndLine();
333                                 }else {
334                                         m->mothurOut("[ERROR]: You don't have any saved reference sequences and the reference parameter is a required."); 
335                                         m->mothurOutEndLine();
336                                         templatefile = ""; abort = true; 
337                                 } 
338                         }
339                                 
340                         string temp = validParameter.validFile(parameters, "processors", false);        if (temp == "not found"){       temp = m->getProcessors();      }
341                         m->setProcessors(temp);
342                         convert(temp, processors);
343                         
344                         abskew = validParameter.validFile(parameters, "abskew", false); if (abskew == "not found"){     useAbskew = false;  abskew = "1.9";     }else{  useAbskew = true;  }
345                         if (useAbskew && templatefile != "self") { m->mothurOut("The abskew parameter is only valid with template=self, ignoring."); m->mothurOutEndLine(); useAbskew = false; }
346                         
347                         temp = validParameter.validFile(parameters, "chimealns", false);                        if (temp == "not found") { temp = "f"; }
348                         chimealns = m->isTrue(temp); 
349                         
350                         minh = validParameter.validFile(parameters, "minh", false);                                             if (minh == "not found")                        { useMinH = false; minh = "0.3";                                        }       else{ useMinH = true;                   }
351                         mindiv = validParameter.validFile(parameters, "mindiv", false);                                 if (mindiv == "not found")                      { useMindiv = false; mindiv = "0.5";                            }       else{ useMindiv = true;                 }
352                         xn = validParameter.validFile(parameters, "xn", false);                                                 if (xn == "not found")                          { useXn = false; xn = "8.0";                                            }       else{ useXn = true;                             }
353                         dn = validParameter.validFile(parameters, "dn", false);                                                 if (dn == "not found")                          { useDn = false; dn = "1.4";                                            }       else{ useDn = true;                             }
354                         xa = validParameter.validFile(parameters, "xa", false);                                                 if (xa == "not found")                          { useXa = false; xa = "1";                                                      }       else{ useXa = true;                             }
355                         chunks = validParameter.validFile(parameters, "chunks", false);                                 if (chunks == "not found")                      { useChunks = false; chunks = "4";                                      }       else{ useChunks = true;                 }
356                         minchunk = validParameter.validFile(parameters, "minchunk", false);                             if (minchunk == "not found")            { useMinchunk = false; minchunk = "64";                         }       else{ useMinchunk = true;               }
357                         idsmoothwindow = validParameter.validFile(parameters, "idsmoothwindow", false); if (idsmoothwindow == "not found")      { useIdsmoothwindow = false; idsmoothwindow = "32";     }       else{ useIdsmoothwindow = true; }
358                         //minsmoothid = validParameter.validFile(parameters, "minsmoothid", false);             if (minsmoothid == "not found")         { useMinsmoothid = false; minsmoothid = "0.95";         }       else{ useMinsmoothid = true;    }
359                         maxp = validParameter.validFile(parameters, "maxp", false);                                             if (maxp == "not found")                        { useMaxp = false; maxp = "2";                                          }       else{ useMaxp = true;                   }
360                         minlen = validParameter.validFile(parameters, "minlen", false);                                 if (minlen == "not found")                      { useMinlen = false; minlen = "10";                                     }       else{ useMinlen = true;                 }
361                         maxlen = validParameter.validFile(parameters, "maxlen", false);                                 if (maxlen == "not found")                      { useMaxlen = false; maxlen = "10000";                          }       else{ useMaxlen = true;                 }
362                         
363                         temp = validParameter.validFile(parameters, "ucl", false);                                              if (temp == "not found") { temp = "f"; }
364                         ucl = m->isTrue(temp);
365                         
366                         queryfract = validParameter.validFile(parameters, "queryfract", false);                 if (queryfract == "not found")          { useQueryfract = false; queryfract = "0.5";            }       else{ useQueryfract = true;             }
367                         if (!ucl && useQueryfract) { m->mothurOut("queryfact may only be used when ucl=t, ignoring."); m->mothurOutEndLine(); useQueryfract = false; }
368                         
369                         temp = validParameter.validFile(parameters, "skipgaps", false);                                 if (temp == "not found") { temp = "t"; }
370                         skipgaps = m->isTrue(temp); 
371
372                         temp = validParameter.validFile(parameters, "skipgaps2", false);                                if (temp == "not found") { temp = "t"; }
373                         skipgaps2 = m->isTrue(temp); 
374                         
375                         if (hasName && (templatefile != "self")) { m->mothurOut("You have provided a namefile and the reference parameter is not set to self. I am not sure what reference you are trying to use, aborting."); m->mothurOutEndLine(); abort=true; }
376                 }
377         }
378         catch(exception& e) {
379                 m->errorOut(e, "ChimeraSlayerCommand", "ChimeraSlayerCommand");
380                 exit(1);
381         }
382 }
383 //***************************************************************************************************************
384
385 int ChimeraUchimeCommand::execute(){
386         try{
387                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
388                 
389                 m->mothurOut("\nuchime by Robert C. Edgar\nhttp://drive5.com/uchime\nThis code is donated to the public domain.\n\n");
390                 
391                 for (int s = 0; s < fastaFileNames.size(); s++) {
392                         
393                         m->mothurOut("Checking sequences from " + fastaFileNames[s] + " ..." ); m->mothurOutEndLine();
394                         
395                         int start = time(NULL); 
396                         string nameFile = "";
397                         
398                         if (templatefile == "self") { //you want to run uchime with a reference template
399                                 
400                                 #ifdef USE_MPI  
401                                         int pid; 
402                                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
403                                         if (pid == 0) { //you are the root process 
404                                 #endif  
405                                 
406                                 if (processors != 1) { m->mothurOut("When using template=self, mothur can only use 1 processor, continuing."); m->mothurOutEndLine(); processors = 1; }
407                                 if (nameFileNames.size() != 0) { //you provided a namefile and we don't need to create one
408                                         nameFile = nameFileNames[s];
409                                 }else {
410                                         m->mothurOutEndLine(); m->mothurOut("No namesfile given, running unique.seqs command to generate one."); m->mothurOutEndLine(); m->mothurOutEndLine();
411                                         
412                                         //use unique.seqs to create new name and fastafile
413                                         string inputString = "fasta=" + fastaFileNames[s];
414                                         m->mothurOut("/******************************************/"); m->mothurOutEndLine(); 
415                                         m->mothurOut("Running command: unique.seqs(" + inputString + ")"); m->mothurOutEndLine(); 
416                                         
417                                         Command* uniqueCommand = new DeconvoluteCommand(inputString);
418                                         uniqueCommand->execute();
419                                         
420                                         map<string, vector<string> > filenames = uniqueCommand->getOutputFiles();
421                                         
422                                         delete uniqueCommand;
423                                         
424                                         m->mothurOut("/******************************************/"); m->mothurOutEndLine(); 
425                                         
426                                         nameFile = filenames["name"][0];
427                                         fastaFileNames[s] = filenames["fasta"][0];
428                                 }
429                                 
430                                 //create input file for uchime
431                                 //read through fastafile and store info
432                                 map<string, string> seqs;
433                                 ifstream in;
434                                 m->openInputFile(fastaFileNames[s], in);
435                                 
436                                 while (!in.eof()) {
437                                         
438                                         if (m->control_pressed) { in.close(); for (int j = 0; j < outputNames.size(); j++) {    m->mothurRemove(outputNames[j]);        }  return 0; }
439                                         
440                                         Sequence seq(in); m->gobble(in);
441                                         seqs[seq.getName()] = seq.getAligned();
442                                 }
443                                 in.close();
444                                 
445                                 //read namefile
446                                 vector<seqPriorityNode> nameMapCount;
447                                 int error = m->readNames(nameFile, nameMapCount, seqs);
448                                 
449                                 if (m->control_pressed) { for (int j = 0; j < outputNames.size(); j++) {        m->mothurRemove(outputNames[j]);        }  return 0; }
450                                 
451                                 if (error == 1) { for (int j = 0; j < outputNames.size(); j++) {        m->mothurRemove(outputNames[j]);        }  return 0; }
452                                 if (seqs.size() != nameMapCount.size()) { m->mothurOut( "The number of sequences in your fastafile does not match the number of sequences in your namefile, aborting."); m->mothurOutEndLine(); for (int j = 0; j < outputNames.size(); j++) {  m->mothurRemove(outputNames[j]);        }  return 0; }
453                                 
454                                 sort(nameMapCount.begin(), nameMapCount.end(), compareSeqPriorityNodes);
455                                 
456                                 string newFasta = m->getRootName(fastaFileNames[s]) + "temp";
457                                 ofstream out;
458                                 m->openOutputFile(newFasta, out);
459                                 
460                                 //print new file in order of
461                                 for (int i = 0; i < nameMapCount.size(); i++) {
462                                         out << ">" << nameMapCount[i].name  << "/ab=" << nameMapCount[i].numIdentical << "/" << endl << nameMapCount[i].seq << endl;
463                                 }
464                                 out.close();
465                                 
466                                 fastaFileNames[s] = newFasta;
467                                                 
468                                 #ifdef USE_MPI  
469                                         }
470                                 #endif
471                                 if (m->control_pressed) {  for (int j = 0; j < outputNames.size(); j++) {       m->mothurRemove(outputNames[j]);        }  return 0;    }                               
472                         }
473                         
474                         if (outputDir == "") { outputDir = m->hasPath(fastaFileNames[s]);  }//if user entered a file with a path then preserve it                               
475                         string outputFileName = outputDir + m->getRootName(m->getSimpleName(fastaFileNames[s])) + "uchime.chimera";
476                         string accnosFileName = outputDir + m->getRootName(m->getSimpleName(fastaFileNames[s]))  + "uchime.accnos";
477                         string alnsFileName = outputDir + m->getRootName(m->getSimpleName(fastaFileNames[s]))  + "uchime.alns";
478                         
479                         if (m->control_pressed) {  for (int j = 0; j < outputNames.size(); j++) {       m->mothurRemove(outputNames[j]);        }  return 0;    }
480                         
481                         int numSeqs = 0;
482 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
483                         if(processors == 1){ numSeqs = driver(outputFileName, fastaFileNames[s], accnosFileName, alnsFileName); }
484                         else{   numSeqs = createProcesses(outputFileName, fastaFileNames[s], accnosFileName, alnsFileName); }
485 #else
486                         numSeqs = driver(outputFileName, fastaFileNames[s], accnosFileName, alnsFileName);
487 #endif
488                         if (m->control_pressed) { for (int j = 0; j < outputNames.size(); j++) {        m->mothurRemove(outputNames[j]);        } return 0; }
489                         
490                         //remove file made for uchime
491                         if (templatefile == "self") {  m->mothurRemove(fastaFileNames[s]); }
492                         
493                         outputNames.push_back(outputFileName); outputTypes["chimera"].push_back(outputFileName);
494                         outputNames.push_back(accnosFileName); outputTypes["accnos"].push_back(accnosFileName);
495                         if (chimealns) { outputNames.push_back(alnsFileName); outputTypes["alns"].push_back(alnsFileName); }
496                         
497                         m->mothurOutEndLine(); m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(numSeqs) + " sequences."); m->mothurOutEndLine();
498                 }
499                 
500                 //set accnos file as new current accnosfile
501                 string current = "";
502                 itTypes = outputTypes.find("accnos");
503                 if (itTypes != outputTypes.end()) {
504                         if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setAccnosFile(current); }
505                 }
506                 
507                 m->mothurOutEndLine();
508                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
509                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }       
510                 m->mothurOutEndLine();
511                 
512                 return 0;
513                 
514         }
515         catch(exception& e) {
516                 m->errorOut(e, "ChimeraUchimeCommand", "execute");
517                 exit(1);
518         }
519 }
520 //**********************************************************************************************************************
521
522 int ChimeraUchimeCommand::driver(string outputFName, string filename, string accnos, string alns){
523         try {
524                 
525                 vector<char*> cPara;
526                 
527                 char* tempUchime = new char[8];  
528                 strcpy(tempUchime, "./uchime "); 
529                 cPara.push_back(tempUchime);
530                 
531                 char* tempIn = new char[8]; 
532                 *tempIn = '\0'; strncat(tempIn, "--input", 7);
533                 //strcpy(tempIn, "--input"); 
534                 cPara.push_back(tempIn);
535                 char* temp = new char[filename.length()+1];
536                 *temp = '\0'; strncat(temp, filename.c_str(), filename.length());
537                 //strcpy(temp, filename.c_str());
538                 cPara.push_back(temp);
539                 
540                 //are you using a reference file
541                 if (templatefile != "self") {
542                         //add reference file
543                         char* tempRef = new char[5]; 
544                         //strcpy(tempRef, "--db"); 
545                         *tempRef = '\0'; strncat(tempRef, "--db", 4);
546                         cPara.push_back(tempRef);  
547                         char* tempR = new char[templatefile.length()+1];
548                         //strcpy(tempR, templatefile.c_str());
549                         *tempR = '\0'; strncat(tempR, templatefile.c_str(), templatefile.length());
550                         cPara.push_back(tempR);
551                 }
552                 
553                 char* tempO = new char[12]; 
554                 *tempO = '\0'; strncat(tempO, "--uchimeout", 11);
555                 //strcpy(tempO, "--uchimeout"); 
556                 cPara.push_back(tempO);
557                 char* tempout = new char[outputFName.length()+1];
558                 //strcpy(tempout, outputFName.c_str());
559                 *tempout = '\0'; strncat(tempout, outputFName.c_str(), outputFName.length());
560                 cPara.push_back(tempout);
561                 
562                 if (chimealns) {
563                         char* tempA = new char[13]; 
564                         *tempA = '\0'; strncat(tempA, "--uchimealns", 12);
565                         //strcpy(tempA, "--uchimealns"); 
566                         cPara.push_back(tempA);
567                         char* tempa = new char[alns.length()+1];
568                         //strcpy(tempa, alns.c_str());
569                         *tempa = '\0'; strncat(tempa, alns.c_str(), alns.length());
570                         cPara.push_back(tempa);
571                 }
572                 
573                 if (useAbskew) {
574                         char* tempskew = new char[9];
575                         *tempskew = '\0'; strncat(tempskew, "--abskew", 8);
576                         //strcpy(tempskew, "--abskew"); 
577                         cPara.push_back(tempskew);
578                         char* tempSkew = new char[abskew.length()+1];
579                         //strcpy(tempSkew, abskew.c_str());
580                         *tempSkew = '\0'; strncat(tempSkew, abskew.c_str(), abskew.length());
581                         cPara.push_back(tempSkew);
582                 }
583                 
584                 if (useMinH) {
585                         char* tempminh = new char[7]; 
586                         *tempminh = '\0'; strncat(tempminh, "--minh", 6);
587                         //strcpy(tempminh, "--minh"); 
588                         cPara.push_back(tempminh);
589                         char* tempMinH = new char[minh.length()+1];
590                         *tempMinH = '\0'; strncat(tempMinH, minh.c_str(), minh.length());
591                         //strcpy(tempMinH, minh.c_str());
592                         cPara.push_back(tempMinH);
593                 }
594                 
595                 if (useMindiv) {
596                         char* tempmindiv = new char[9]; 
597                         *tempmindiv = '\0'; strncat(tempmindiv, "--mindiv", 8);
598                         //strcpy(tempmindiv, "--mindiv"); 
599                         cPara.push_back(tempmindiv);
600                         char* tempMindiv = new char[mindiv.length()+1];
601                         *tempMindiv = '\0'; strncat(tempMindiv, mindiv.c_str(), mindiv.length());
602                         //strcpy(tempMindiv, mindiv.c_str());
603                         cPara.push_back(tempMindiv);
604                 }
605                 
606                 if (useXn) {
607                         char* tempxn = new char[5]; 
608                         //strcpy(tempxn, "--xn"); 
609                         *tempxn = '\0'; strncat(tempxn, "--xn", 4);
610                         cPara.push_back(tempxn);
611                         char* tempXn = new char[xn.length()+1];
612                         //strcpy(tempXn, xn.c_str());
613                         *tempXn = '\0'; strncat(tempXn, xn.c_str(), xn.length());
614                         cPara.push_back(tempXn);
615                 }
616                 
617                 if (useDn) {
618                         char* tempdn = new char[5]; 
619                         //strcpy(tempdn, "--dn"); 
620                         *tempdn = '\0'; strncat(tempdn, "--dn", 4);
621                         cPara.push_back(tempdn);
622                         char* tempDn = new char[dn.length()+1];
623                         *tempDn = '\0'; strncat(tempDn, dn.c_str(), dn.length());
624                         //strcpy(tempDn, dn.c_str());
625                         cPara.push_back(tempDn);
626                 }
627                 
628                 if (useXa) {
629                         char* tempxa = new char[5]; 
630                         //strcpy(tempxa, "--xa"); 
631                         *tempxa = '\0'; strncat(tempxa, "--xa", 4);
632                         cPara.push_back(tempxa);
633                         char* tempXa = new char[xa.length()+1];
634                         *tempXa = '\0'; strncat(tempXa, xa.c_str(), xa.length());
635                         //strcpy(tempXa, xa.c_str());
636                         cPara.push_back(tempXa);
637                 }
638                 
639                 if (useChunks) {
640                         char* tempchunks = new char[9]; 
641                         //strcpy(tempchunks, "--chunks"); 
642                         *tempchunks = '\0'; strncat(tempchunks, "--chunks", 8);
643                         cPara.push_back(tempchunks);
644                         char* tempChunks = new char[chunks.length()+1];
645                         *tempChunks = '\0'; strncat(tempChunks, chunks.c_str(), chunks.length());
646                         //strcpy(tempChunks, chunks.c_str());
647                         cPara.push_back(tempChunks);
648                 }
649                 
650                 if (useMinchunk) {
651                         char* tempminchunk = new char[11]; 
652                         //strcpy(tempminchunk, "--minchunk"); 
653                         *tempminchunk = '\0'; strncat(tempminchunk, "--minchunk", 10);
654                         cPara.push_back(tempminchunk);
655                         char* tempMinchunk = new char[minchunk.length()+1];
656                         *tempMinchunk = '\0'; strncat(tempMinchunk, minchunk.c_str(), minchunk.length());
657                         //strcpy(tempMinchunk, minchunk.c_str());
658                         cPara.push_back(tempMinchunk);
659                 }
660                 
661                 if (useIdsmoothwindow) {
662                         char* tempidsmoothwindow = new char[17]; 
663                         *tempidsmoothwindow = '\0'; strncat(tempidsmoothwindow, "--idsmoothwindow", 16);
664                         //strcpy(tempidsmoothwindow, "--idsmoothwindow"); 
665                         cPara.push_back(tempidsmoothwindow);
666                         char* tempIdsmoothwindow = new char[idsmoothwindow.length()+1];
667                         *tempIdsmoothwindow = '\0'; strncat(tempIdsmoothwindow, idsmoothwindow.c_str(), idsmoothwindow.length());
668                         //strcpy(tempIdsmoothwindow, idsmoothwindow.c_str());
669                         cPara.push_back(tempIdsmoothwindow);
670                 }
671                 
672                 /*if (useMinsmoothid) {
673                         char* tempminsmoothid = new char[14]; 
674                         //strcpy(tempminsmoothid, "--minsmoothid"); 
675                         *tempminsmoothid = '\0'; strncat(tempminsmoothid, "--minsmoothid", 13);
676                         cPara.push_back(tempminsmoothid);
677                         char* tempMinsmoothid = new char[minsmoothid.length()+1];
678                         *tempMinsmoothid = '\0'; strncat(tempMinsmoothid, minsmoothid.c_str(), minsmoothid.length());
679                         //strcpy(tempMinsmoothid, minsmoothid.c_str());
680                         cPara.push_back(tempMinsmoothid);
681                 }*/
682                 
683                 if (useMaxp) {
684                         char* tempmaxp = new char[7]; 
685                         //strcpy(tempmaxp, "--maxp"); 
686                         *tempmaxp = '\0'; strncat(tempmaxp, "--maxp", 6);
687                         cPara.push_back(tempmaxp);
688                         char* tempMaxp = new char[maxp.length()+1];
689                         *tempMaxp = '\0'; strncat(tempMaxp, maxp.c_str(), maxp.length());
690                         //strcpy(tempMaxp, maxp.c_str());
691                         cPara.push_back(tempMaxp);
692                 }
693                 
694                 if (!skipgaps) {
695                         char* tempskipgaps = new char[13]; 
696                         //strcpy(tempskipgaps, "--[no]skipgaps");
697                         *tempskipgaps = '\0'; strncat(tempskipgaps, "--noskipgaps", 12);
698                         cPara.push_back(tempskipgaps);
699                 }
700                 
701                 if (!skipgaps2) {
702                         char* tempskipgaps2 = new char[14]; 
703                         //strcpy(tempskipgaps2, "--[no]skipgaps2"); 
704                         *tempskipgaps2 = '\0'; strncat(tempskipgaps2, "--noskipgaps2", 13);
705                         cPara.push_back(tempskipgaps2);
706                 }
707                 
708                 if (useMinlen) {
709                         char* tempminlen = new char[9]; 
710                         *tempminlen = '\0'; strncat(tempminlen, "--minlen", 8);
711                         //strcpy(tempminlen, "--minlen"); 
712                         cPara.push_back(tempminlen);
713                         char* tempMinlen = new char[minlen.length()+1];
714                         //strcpy(tempMinlen, minlen.c_str());
715                         *tempMinlen = '\0'; strncat(tempMinlen, minlen.c_str(), minlen.length());
716                         cPara.push_back(tempMinlen);
717                 }
718                 
719                 if (useMaxlen) {
720                         char* tempmaxlen = new char[9]; 
721                         //strcpy(tempmaxlen, "--maxlen"); 
722                         *tempmaxlen = '\0'; strncat(tempmaxlen, "--maxlen", 8);
723                         cPara.push_back(tempmaxlen);
724                         char* tempMaxlen = new char[maxlen.length()+1];
725                         *tempMaxlen = '\0'; strncat(tempMaxlen, maxlen.c_str(), maxlen.length());
726                         //strcpy(tempMaxlen, maxlen.c_str());
727                         cPara.push_back(tempMaxlen);
728                 }
729                 
730                 if (ucl) {
731                         char* tempucl = new char[5]; 
732                         strcpy(tempucl, "--ucl"); 
733                         cPara.push_back(tempucl);
734                 }
735                 
736                 if (useQueryfract) {
737                         char* tempqueryfract = new char[13]; 
738                         *tempqueryfract = '\0'; strncat(tempqueryfract, "--queryfract", 12);
739                         //strcpy(tempqueryfract, "--queryfract"); 
740                         cPara.push_back(tempqueryfract);
741                         char* tempQueryfract = new char[queryfract.length()+1];
742                         *tempQueryfract = '\0'; strncat(tempQueryfract, queryfract.c_str(), queryfract.length());
743                         //strcpy(tempQueryfract, queryfract.c_str());
744                         cPara.push_back(tempQueryfract);
745                 }
746                 
747                 
748                 char** uchimeParameters;
749                 uchimeParameters = new char*[cPara.size()];
750                 for (int i = 0; i < cPara.size(); i++) {  uchimeParameters[i] = cPara[i];  } 
751                 int numArgs = cPara.size();
752                 
753                 uchime_main(numArgs, uchimeParameters); 
754                 
755                 //free memory
756                 for(int i = 0; i < cPara.size(); i++)  {  delete[] cPara[i];  }
757                 delete[] uchimeParameters; 
758                 
759                 if (m->control_pressed) { return 0; }
760                 
761                 //create accnos file from uchime results
762                 ifstream in; 
763                 m->openInputFile(outputFName, in);
764                 
765                 ofstream out;
766                 m->openOutputFile(accnos, out);
767                 
768                 int num = 0;
769                 while(!in.eof()) {
770                         
771                         if (m->control_pressed) { break; }
772                         
773                         string name = "";
774                         string chimeraFlag = "";
775                         in >> chimeraFlag >> name;
776                         
777                         //fix name if needed
778                         if (templatefile == "self") { 
779                                 name = name.substr(0, name.length()-1); //rip off last /
780                                 name = name.substr(0, name.find_last_of('/'));
781                         }
782                         
783                         for (int i = 0; i < 15; i++) {  in >> chimeraFlag; }
784                         m->gobble(in);
785                         
786                         if (chimeraFlag == "Y") {  out << name << endl; }
787                         num++;
788                 }
789                 in.close();
790                 out.close();
791                 
792                 return num;
793         }
794         catch(exception& e) {
795                 m->errorOut(e, "ChimeraUchimeCommand", "driver");
796                 exit(1);
797         }
798 }
799 /**************************************************************************************************/
800
801 int ChimeraUchimeCommand::createProcesses(string outputFileName, string filename, string accnos, string alns) {
802         try {
803                 
804                 processIDS.clear();
805                 int process = 1;
806                 int num = 0;
807 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)           
808                 //break up file into multiple files
809                 vector<string> files;
810                 m->divideFile(filename, processors, files);
811                 
812                 if (m->control_pressed) {  return 0;  }
813                 
814 #ifdef USE_MPI  
815                 int pid, numSeqsPerProcessor; 
816                 int tag = 2001;
817                 
818                 MPI_Status status; 
819                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
820                 MPI_Comm_size(MPI_COMM_WORLD, &processors); 
821                                 
822                 if (pid == 0) { //you are the root process 
823                         num = driver(outputFileName, files[0], accnos, alns);
824                         
825                         if (templatefile != "self") {
826                                 //wait on chidren
827                                 for(int j = 1; j < processors; j++) { 
828                                         int temp;
829                                         MPI_Recv(&temp, 1, MPI_INT, j, tag, MPI_COMM_WORLD, &status);
830                                         num += temp;
831                                         
832                                         m->appendFiles((outputFileName + toString(j) + ".temp"), outputFileName);
833                                         m->mothurRemove((outputFileName + toString(j) + ".temp"));
834                                         
835                                         m->appendFiles((accnos + toString(j) + ".temp"), accnos);
836                                         m->mothurRemove((accnos + toString(j) + ".temp"));
837                                         
838                                         if (chimealns) {
839                                                 m->appendFiles((alns + toString(j) + ".temp"), alns);
840                                                 m->mothurRemove((alns + toString(j) + ".temp"));
841                                         }
842                                 }
843                         }
844                 }else{ //you are a child process
845                         if (templatefile != "self") { //if template=self we can only use 1 processor
846                                 num = driver(outputFileName+toString(pid) + ".temp", files[pid], accnos+toString(pid) + ".temp", alns+toString(pid) + ".temp"); 
847                                 
848                                 //send numSeqs to parent
849                                 MPI_Send(&num, 1, MPI_INT, 0, tag, MPI_COMM_WORLD);
850                         }
851                 }
852
853                 MPI_Barrier(MPI_COMM_WORLD); //make everyone wait - just in case
854 #else
855                 
856                 //loop through and create all the processes you want
857                 while (process != processors) {
858                         int pid = fork();
859                         
860                         if (pid > 0) {
861                                 processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
862                                 process++;
863                         }else if (pid == 0){
864                                 num = driver(outputFileName + toString(getpid()) + ".temp", files[process], accnos + toString(getpid()) + ".temp", alns + toString(getpid()) + ".temp");
865                                 
866                                 //pass numSeqs to parent
867                                 ofstream out;
868                                 string tempFile = outputFileName + toString(getpid()) + ".num.temp";
869                                 m->openOutputFile(tempFile, out);
870                                 out << num << endl;
871                                 out.close();
872                                 
873                                 exit(0);
874                         }else { 
875                                 m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
876                                 for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
877                                 exit(0);
878                         }
879                 }
880                 
881                 //do my part
882                 num = driver(outputFileName, files[0], accnos, alns);
883                 
884                 //force parent to wait until all the processes are done
885                 for (int i=0;i<processIDS.size();i++) { 
886                         int temp = processIDS[i];
887                         wait(&temp);
888                 }
889                 
890                 for (int i = 0; i < processIDS.size(); i++) {
891                         ifstream in;
892                         string tempFile =  outputFileName + toString(processIDS[i]) + ".num.temp";
893                         m->openInputFile(tempFile, in);
894                         if (!in.eof()) { int tempNum = 0; in >> tempNum; num += tempNum; }
895                         in.close(); m->mothurRemove(tempFile);
896                 }
897                 
898                 
899                 //append output files
900                 for(int i=0;i<processIDS[i];i++){
901                         m->appendFiles((outputFileName + toString(processIDS[i]) + ".temp"), outputFileName);
902                         m->mothurRemove((outputFileName + toString(processIDS[i]) + ".temp"));
903                         
904                         m->appendFiles((accnos + toString(processIDS[i]) + ".temp"), accnos);
905                         m->mothurRemove((accnos + toString(processIDS[i]) + ".temp"));
906                         
907                         if (chimealns) {
908                                 m->appendFiles((alns + toString(processIDS[i]) + ".temp"), alns);
909                                 m->mothurRemove((alns + toString(processIDS[i]) + ".temp"));
910                         }
911                 }
912 #endif          
913                 //get rid of the file pieces.
914                 for (int i = 0; i < files.size(); i++) { m->mothurRemove(files[i]); }
915 #endif          
916                 return num;     
917         }
918         catch(exception& e) {
919                 m->errorOut(e, "ChimeraUchimeCommand", "createProcesses");
920                 exit(1);
921         }
922 }
923
924 /**************************************************************************************************/
925