]> git.donarmstrong.com Git - mothur.git/blob - chimerauchimecommand.cpp
added chimera.uchime
[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
15
16 //**********************************************************************************************************************
17 vector<string> ChimeraUchimeCommand::setParameters(){   
18         try {
19                 CommandParameter ptemplate("reference", "InputTypes", "", "", "none", "none", "none",false,true); parameters.push_back(ptemplate);
20                 CommandParameter pfasta("fasta", "InputTypes", "", "", "none", "none", "none",false,true); parameters.push_back(pfasta);
21                 CommandParameter pname("name", "InputTypes", "", "", "none", "none", "none",false,false); parameters.push_back(pname);
22                 CommandParameter pprocessors("processors", "Number", "", "1", "", "", "",false,false); parameters.push_back(pprocessors);
23                 CommandParameter pinputdir("inputdir", "String", "", "", "", "", "",false,false); parameters.push_back(pinputdir);
24                 CommandParameter poutputdir("outputdir", "String", "", "", "", "", "",false,false); parameters.push_back(poutputdir);
25                 
26                 vector<string> myArray;
27                 for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
28                 return myArray;
29         }
30         catch(exception& e) {
31                 m->errorOut(e, "ChimeraUchimeCommand", "setParameters");
32                 exit(1);
33         }
34 }
35 //**********************************************************************************************************************
36 string ChimeraUchimeCommand::getHelpString(){   
37         try {
38                 string helpString = "";
39                 helpString += "The chimera.uchime command reads a fastafile and referencefile and outputs potentially chimeric sequences.\n";
40                 helpString += "This command is a wrapper for uchime written by Robert C. Edgar.\n";
41                 helpString += "The chimera.uchime command parameters are fasta, name, reference and processors.\n";
42                 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";
43                 helpString += "The name parameter allows you to provide a name file, if you are using template=self. \n";
44                 helpString += "You may enter multiple fasta files by separating their names with dashes. ie. fasta=abrecovery.fasta-amazon.fasta \n";
45                 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";
46                 helpString += "The processors parameter allows you to specify how many processors you would like to use.  The default is 1. \n";
47 #ifdef USE_MPI
48                 helpString += "When using MPI, the processors parameter is set to the number of MPI processes running. \n";
49 #endif
50                 helpString += "The chimera.uchime command should be in the following format: \n";
51                 helpString += "chimera.uchime(fasta=yourFastaFile, reference=yourTemplate) \n";
52                 helpString += "Example: chimera.uchime(fasta=AD.align, reference=silva.gold.align) \n";
53                 helpString += "Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFastaFile).\n";       
54                 return helpString;
55         }
56         catch(exception& e) {
57                 m->errorOut(e, "ChimeraUchimeCommand", "getHelpString");
58                 exit(1);
59         }
60 }
61 //**********************************************************************************************************************
62 ChimeraUchimeCommand::ChimeraUchimeCommand(){   
63         try {
64                 abort = true; calledHelp = true;
65                 setParameters();
66                 vector<string> tempOutNames;
67                 outputTypes["chimera"] = tempOutNames;
68                 outputTypes["accnos"] = tempOutNames;
69         }
70         catch(exception& e) {
71                 m->errorOut(e, "ChimeraUchimeCommand", "ChimeraUchimeCommand");
72                 exit(1);
73         }
74 }
75 //***************************************************************************************************************
76 ChimeraUchimeCommand::ChimeraUchimeCommand(string option)  {
77         try {
78                 abort = false; calledHelp = false;   
79                 
80                 //allow user to run help
81                 if(option == "help") { help(); abort = true; calledHelp = true; }
82                 else if(option == "citation") { citation(); abort = true; calledHelp = true;}
83                 
84                 else {
85                         vector<string> myArray = setParameters();
86                         
87                         OptionParser parser(option);
88                         map<string,string> parameters = parser.getParameters();
89                         
90                         ValidParameters validParameter("chimera.uchime");
91                         map<string,string>::iterator it;
92                         
93                         //check to make sure all parameters are valid for command
94                         for (it = parameters.begin(); it != parameters.end(); it++) { 
95                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
96                         }
97                         
98                         vector<string> tempOutNames;
99                         outputTypes["chimera"] = tempOutNames;
100                         outputTypes["accnos"] = tempOutNames;
101                         
102                         //if the user changes the input directory command factory will send this info to us in the output parameter 
103                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
104                         if (inputDir == "not found"){   inputDir = "";          }
105                         
106                         //check for required parameters
107                         fastafile = validParameter.validFile(parameters, "fasta", false);
108                         if (fastafile == "not found") {                                 
109                                 //if there is a current fasta file, use it
110                                 string filename = m->getFastaFile(); 
111                                 if (filename != "") { fastaFileNames.push_back(filename); m->mothurOut("Using " + filename + " as input file for the fasta parameter."); m->mothurOutEndLine(); }
112                                 else {  m->mothurOut("You have no current fastafile and the fasta parameter is required."); m->mothurOutEndLine(); abort = true; }
113                         }else { 
114                                 m->splitAtDash(fastafile, fastaFileNames);
115                                 
116                                 //go through files and make sure they are good, if not, then disregard them
117                                 for (int i = 0; i < fastaFileNames.size(); i++) {
118                                         
119                                         bool ignore = false;
120                                         if (fastaFileNames[i] == "current") { 
121                                                 fastaFileNames[i] = m->getFastaFile(); 
122                                                 if (fastaFileNames[i] != "") {  m->mothurOut("Using " + fastaFileNames[i] + " as input file for the fasta parameter where you had given current."); m->mothurOutEndLine(); }
123                                                 else {  
124                                                         m->mothurOut("You have no current fastafile, ignoring current."); m->mothurOutEndLine(); ignore=true; 
125                                                         //erase from file list
126                                                         fastaFileNames.erase(fastaFileNames.begin()+i);
127                                                         i--;
128                                                 }
129                                         }
130                                         
131                                         if (!ignore) {
132                                                 
133                                                 if (inputDir != "") {
134                                                         string path = m->hasPath(fastaFileNames[i]);
135                                                         //if the user has not given a path then, add inputdir. else leave path alone.
136                                                         if (path == "") {       fastaFileNames[i] = inputDir + fastaFileNames[i];               }
137                                                 }
138                                                 
139                                                 int ableToOpen;
140                                                 ifstream in;
141                                                 
142                                                 ableToOpen = m->openInputFile(fastaFileNames[i], in, "noerror");
143                                                 
144                                                 //if you can't open it, try default location
145                                                 if (ableToOpen == 1) {
146                                                         if (m->getDefaultPath() != "") { //default path is set
147                                                                 string tryPath = m->getDefaultPath() + m->getSimpleName(fastaFileNames[i]);
148                                                                 m->mothurOut("Unable to open " + fastaFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
149                                                                 ifstream in2;
150                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
151                                                                 in2.close();
152                                                                 fastaFileNames[i] = tryPath;
153                                                         }
154                                                 }
155                                                 
156                                                 if (ableToOpen == 1) {
157                                                         if (m->getOutputDir() != "") { //default path is set
158                                                                 string tryPath = m->getOutputDir() + m->getSimpleName(fastaFileNames[i]);
159                                                                 m->mothurOut("Unable to open " + fastaFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
160                                                                 ifstream in2;
161                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
162                                                                 in2.close();
163                                                                 fastaFileNames[i] = tryPath;
164                                                         }
165                                                 }
166                                                 
167                                                 in.close();
168                                                 
169                                                 if (ableToOpen == 1) { 
170                                                         m->mothurOut("Unable to open " + fastaFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine(); 
171                                                         //erase from file list
172                                                         fastaFileNames.erase(fastaFileNames.begin()+i);
173                                                         i--;
174                                                 }
175                                         }
176                                 }
177                                 
178                                 //make sure there is at least one valid file left
179                                 if (fastaFileNames.size() == 0) { m->mothurOut("[ERROR]: no valid files."); m->mothurOutEndLine(); abort = true; }
180                         }
181                         
182                         
183                         //check for required parameters
184                         bool hasName = true;
185                         namefile = validParameter.validFile(parameters, "name", false);
186                         if (namefile == "not found") { namefile = "";  hasName = false; }
187                         else { 
188                                 m->splitAtDash(namefile, nameFileNames);
189                                 
190                                 //go through files and make sure they are good, if not, then disregard them
191                                 for (int i = 0; i < nameFileNames.size(); i++) {
192                                         
193                                         bool ignore = false;
194                                         if (nameFileNames[i] == "current") { 
195                                                 nameFileNames[i] = m->getNameFile(); 
196                                                 if (nameFileNames[i] != "") {  m->mothurOut("Using " + nameFileNames[i] + " as input file for the name parameter where you had given current."); m->mothurOutEndLine(); }
197                                                 else {  
198                                                         m->mothurOut("You have no current namefile, ignoring current."); m->mothurOutEndLine(); ignore=true; 
199                                                         //erase from file list
200                                                         nameFileNames.erase(nameFileNames.begin()+i);
201                                                         i--;
202                                                 }
203                                         }
204                                         
205                                         if (!ignore) {
206                                                 
207                                                 if (inputDir != "") {
208                                                         string path = m->hasPath(nameFileNames[i]);
209                                                         //if the user has not given a path then, add inputdir. else leave path alone.
210                                                         if (path == "") {       nameFileNames[i] = inputDir + nameFileNames[i];         }
211                                                 }
212                                                 
213                                                 int ableToOpen;
214                                                 ifstream in;
215                                                 
216                                                 ableToOpen = m->openInputFile(nameFileNames[i], in, "noerror");
217                                                 
218                                                 //if you can't open it, try default location
219                                                 if (ableToOpen == 1) {
220                                                         if (m->getDefaultPath() != "") { //default path is set
221                                                                 string tryPath = m->getDefaultPath() + m->getSimpleName(nameFileNames[i]);
222                                                                 m->mothurOut("Unable to open " + nameFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
223                                                                 ifstream in2;
224                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
225                                                                 in2.close();
226                                                                 nameFileNames[i] = tryPath;
227                                                         }
228                                                 }
229                                                 
230                                                 if (ableToOpen == 1) {
231                                                         if (m->getOutputDir() != "") { //default path is set
232                                                                 string tryPath = m->getOutputDir() + m->getSimpleName(nameFileNames[i]);
233                                                                 m->mothurOut("Unable to open " + nameFileNames[i] + ". Trying output directory " + tryPath); m->mothurOutEndLine();
234                                                                 ifstream in2;
235                                                                 ableToOpen = m->openInputFile(tryPath, in2, "noerror");
236                                                                 in2.close();
237                                                                 nameFileNames[i] = tryPath;
238                                                         }
239                                                 }
240                                                 
241                                                 in.close();
242                                                 
243                                                 if (ableToOpen == 1) { 
244                                                         m->mothurOut("Unable to open " + nameFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine(); 
245                                                         //erase from file list
246                                                         nameFileNames.erase(nameFileNames.begin()+i);
247                                                         i--;
248                                                 }
249                                         }
250                                 }
251                                 
252                                 //make sure there is at least one valid file left
253                                 if (nameFileNames.size() == 0) { m->mothurOut("[ERROR]: no valid name files."); m->mothurOutEndLine(); abort = true; }
254                         }
255                         
256                         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; }
257                         
258                         //if the user changes the output directory command factory will send this info to us in the output parameter 
259                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = ""; }
260                         
261                         
262                         string path;
263                         it = parameters.find("reference");
264                         //user has given a template file
265                         if(it != parameters.end()){ 
266                                 if (it->second == "self") { templatefile = "self"; }
267                                 else {
268                                         path = m->hasPath(it->second);
269                                         //if the user has not given a path then, add inputdir. else leave path alone.
270                                         if (path == "") {       parameters["reference"] = inputDir + it->second;                }
271                                         
272                                         templatefile = validParameter.validFile(parameters, "reference", true);
273                                         if (templatefile == "not open") { abort = true; }
274                                         else if (templatefile == "not found") { templatefile = "";  m->mothurOut("reference is a required parameter for the chimera.slayer command."); m->mothurOutEndLine(); abort = true;  }  
275                                 }
276                         }
277                         
278                         string temp = validParameter.validFile(parameters, "processors", false);        if (temp == "not found"){       temp = m->getProcessors();      }
279                         m->setProcessors(temp);
280                         convert(temp, processors);
281                 }
282         }
283         catch(exception& e) {
284                 m->errorOut(e, "ChimeraSlayerCommand", "ChimeraSlayerCommand");
285                 exit(1);
286         }
287 }
288 //***************************************************************************************************************
289
290 int ChimeraUchimeCommand::execute(){
291         try{
292                 if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
293                 
294                 for (int s = 0; s < fastaFileNames.size(); s++) {
295                         
296                         m->mothurOut("Checking sequences from " + fastaFileNames[s] + " ..." ); m->mothurOutEndLine();
297                         
298                         int start = time(NULL); 
299                         string nameFile = "";
300                         
301                         if (templatefile == "self") { //you want to run slayer with a refernce template
302                                 
303                                 #ifdef USE_MPI  
304                                         int pid; 
305                                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
306                                         if (pid == 0) { //you are the root process 
307                                 #endif  
308                                 
309                                 if (processors != 1) { m->mothurOut("When using template=self, mothur can only use 1 processor, continuing."); m->mothurOutEndLine(); processors = 1; }
310                                 if (nameFileNames.size() != 0) { //you provided a namefile and we don't need to create one
311                                         nameFile = nameFileNames[s];
312                                 }else {
313                                         m->mothurOutEndLine(); m->mothurOut("No namesfile given, running unique.seqs command to generate one."); m->mothurOutEndLine(); m->mothurOutEndLine();
314                                         
315                                         //use unique.seqs to create new name and fastafile
316                                         string inputString = "fasta=" + fastaFileNames[s];
317                                         m->mothurOut("/******************************************/"); m->mothurOutEndLine(); 
318                                         m->mothurOut("Running command: unique.seqs(" + inputString + ")"); m->mothurOutEndLine(); 
319                                         
320                                         Command* uniqueCommand = new DeconvoluteCommand(inputString);
321                                         uniqueCommand->execute();
322                                         
323                                         map<string, vector<string> > filenames = uniqueCommand->getOutputFiles();
324                                         
325                                         delete uniqueCommand;
326                                         
327                                         m->mothurOut("/******************************************/"); m->mothurOutEndLine(); 
328                                         
329                                         nameFile = filenames["name"][0];
330                                         fastaFileNames[s] = filenames["fasta"][0];
331                                 }
332                                 
333                                 //create input file for uchime
334                                 //read through fastafile and store info
335                                 map<string, string> seqs;
336                                 ifstream in;
337                                 m->openInputFile(fastaFileNames[s], in);
338                                 
339                                 while (!in.eof()) {
340                                         
341                                         if (m->control_pressed) { in.close(); for (int j = 0; j < outputNames.size(); j++) {    remove(outputNames[j].c_str()); }  return 0; }
342                                         
343                                         Sequence seq(in); m->gobble(in);
344                                         seqs[seq.getName()] = seq.getAligned();
345                                 }
346                                 in.close();
347                                 
348                                 //read namefile
349                                 vector<seqPriorityNode> nameMapCount;
350                                 int error = m->readNames(nameFile, nameMapCount, seqs);
351                                 
352                                 if (m->control_pressed) { for (int j = 0; j < outputNames.size(); j++) {        remove(outputNames[j].c_str()); }  return 0; }
353                                 
354                                 if (error == 1) { for (int j = 0; j < outputNames.size(); j++) {        remove(outputNames[j].c_str()); }  return 0; }
355                                 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++) {  remove(outputNames[j].c_str()); }  return 0; }
356                                 
357                                 sort(nameMapCount.begin(), nameMapCount.end(), compareSeqPriorityNodes);
358                                 
359                                 string newFasta = fastaFileNames[s] + ".temp";
360                                 ofstream out;
361                                 m->openOutputFile(newFasta, out);
362                                 
363                                 //print new file in order of
364                                 for (int i = 0; i < nameMapCount.size(); i++) {
365                                         out << ">" << nameMapCount[i].name  << "/ab=" << nameMapCount[i].numIdentical << "/" << endl << nameMapCount[i].seq << endl;
366                                 }
367                                 out.close();
368                                 
369                                 fastaFileNames[s] = newFasta;
370                                                 
371                                 #ifdef USE_MPI  
372                                         }
373                                 #endif
374                                 if (m->control_pressed) {  for (int j = 0; j < outputNames.size(); j++) {       remove(outputNames[j].c_str()); }  return 0;    }                               
375                         }
376                         
377                         if (outputDir == "") { outputDir = m->hasPath(fastaFileNames[s]);  }//if user entered a file with a path then preserve it                               
378                         string outputFileName = outputDir + m->getRootName(m->getSimpleName(fastaFileNames[s])) + "slayer.chimera";
379                         string accnosFileName = outputDir + m->getRootName(m->getSimpleName(fastaFileNames[s]))  + "slayer.accnos";
380                         
381                         if (m->control_pressed) {  for (int j = 0; j < outputNames.size(); j++) {       remove(outputNames[j].c_str()); }  return 0;    }
382                         
383                         int numSeqs = 0;
384 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
385                         if(processors == 1){ numSeqs = driver(outputFileName, fastaFileNames[s], accnosFileName); }
386                         else{   numSeqs = createProcesses(outputFileName, fastaFileNames[s], accnosFileName); }
387 #else
388                         numSeqs = driver(outputFileName, fastaFileNames[s], accnosFileName);
389 #endif
390                         if (m->control_pressed) { for (int j = 0; j < outputNames.size(); j++) {        remove(outputNames[j].c_str()); } return 0; }
391
392                         
393                         outputNames.push_back(outputFileName); outputTypes["chimera"].push_back(outputFileName);
394                         outputNames.push_back(accnosFileName); outputTypes["accnos"].push_back(accnosFileName);
395                         
396                         m->mothurOutEndLine(); m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(numSeqs) + " sequences."); m->mothurOutEndLine();
397                 }
398                 
399                 //set accnos file as new current accnosfile
400                 string current = "";
401                 itTypes = outputTypes.find("accnos");
402                 if (itTypes != outputTypes.end()) {
403                         if ((itTypes->second).size() != 0) { current = (itTypes->second)[0]; m->setAccnosFile(current); }
404                 }
405                 
406                 m->mothurOutEndLine();
407                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
408                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }       
409                 m->mothurOutEndLine();
410                 
411                 return 0;
412                 
413         }
414         catch(exception& e) {
415                 m->errorOut(e, "ChimeraUchimeCommand", "execute");
416                 exit(1);
417         }
418 }
419 //**********************************************************************************************************************
420
421 int ChimeraUchimeCommand::driver(string outputFName, string filename, string accnos){
422         try {
423                 
424                 vector<char*> cPara;
425                 
426                 char* tempUchime = new char[8];  
427                 strcpy(tempUchime, "./uchime "); 
428                 cPara.push_back(tempUchime);
429                 
430                 char* tempIn = new char[7];  
431                 strcpy(tempIn, "--input"); 
432                 cPara.push_back(tempIn);
433                 char* temp = new char[filename.length()];
434                 strcpy(temp, filename.c_str());
435                 cPara.push_back(temp);
436                 
437                 //are you using a reference file
438                 if (templatefile != "self") {
439                                                 
440                         //add reference file
441                         char* tempRef = new char[4]; 
442                         strcpy(tempRef, "--db"); 
443                         cPara.push_back(tempRef);  
444                         char* tempR = new char[templatefile.length()];
445                         strcpy(tempR, templatefile.c_str());
446                         cPara.push_back(tempR);
447                 }
448                 
449                 char* tempO = new char[11]; 
450                 strcpy(tempO, "--uchimeout"); 
451                 cPara.push_back(tempO);
452                 char* tempout = new char[outputFName.length()];
453                 strcpy(tempout, outputFName.c_str());
454                 cPara.push_back(tempout);
455                 
456                 char** uchimeParameters;
457                 uchimeParameters = new char*[cPara.size()];
458                 for (int i = 0; i < cPara.size(); i++) {  uchimeParameters[i] = cPara[i];  } 
459                 int numArgs = cPara.size();
460                 
461                 uchime_main(numArgs, uchimeParameters); 
462                 
463                 //free memory
464                 for(int i = 0; i < cPara.size(); i++)  {  delete[] cPara[i];  }
465                 delete[] uchimeParameters; 
466                 
467                 //create accnos file from uchime results
468                 ifstream in; 
469                 m->openInputFile(outputFName, in);
470                 
471                 ofstream out;
472                 m->openOutputFile(accnos, out);
473                 
474                 int num = 0;
475                 while(!in.eof()) {
476                         
477                         if (m->control_pressed) { break; }
478                         
479                         string name = "";
480                         string chimeraFlag = "";
481                         in >> chimeraFlag >> name;
482                         
483                         //fix name if needed
484                         if (templatefile != "self") { 
485                                 name = name.substr(0, name.length()-1); //rip off last /
486                                 name = name.substr(0, name.find_last_of('/'));
487                         }
488                         
489                         for (int i = 0; i < 15; i++) {  in >> chimeraFlag; }
490                         m->gobble(in);
491                         
492                         if (chimeraFlag == "Y") {  out << name << endl; }
493                         num++;
494                 }
495                 in.close();
496                 out.close();
497                 
498                 return num;
499         }
500         catch(exception& e) {
501                 m->errorOut(e, "ChimeraUchimeCommand", "driver");
502                 exit(1);
503         }
504 }
505 /**************************************************************************************************/
506
507 int ChimeraUchimeCommand::createProcesses(string outputFileName, string filename, string accnos) {
508         try {
509                 
510                 processIDS.clear();
511                 int process = 1;
512                 int num = 0;
513                 
514                 //break up file into multiple files
515                 vector<string> files;
516                 m->divideFile(filename, processors, files);
517                 
518                 if (m->control_pressed) {  return 0;  }
519                 
520 #ifdef USE_MPI  
521                 int pid, numSeqsPerProcessor; 
522                 int tag = 2001;
523                 
524                 MPI_Status status; 
525                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
526                 MPI_Comm_size(MPI_COMM_WORLD, &processors); 
527                                 
528                 if (pid == 0) { //you are the root process 
529                         num = driver(outputFileName, files[0], accnos);
530                         
531                         if (templatefile != "self") {
532                                 //wait on chidren
533                                 for(int j = 1; j < processors; j++) { 
534                                         int temp;
535                                         MPI_Recv(&temp, 1, MPI_INT, j, tag, MPI_COMM_WORLD, &status);
536                                         num += temp;
537                                         
538                                         m->appendFiles((outputFileName + toString(j) + ".temp"), outputFileName);
539                                         remove((outputFileName + toString(j) + ".temp").c_str());
540                                         
541                                         m->appendFiles((accnos + toString(j) + ".temp"), accnos);
542                                         remove((accnos + toString(j) + ".temp").c_str());
543                                 }
544                         }
545                 }else{ //you are a child process
546                         if (templatefile != "self") { //if template=self we can only use 1 processor
547                                 num = driver(outputFileName+toString(pid) + ".temp", files[pid], accnos+toString(pid) + ".temp");       
548                                 
549                                 //send numSeqs to parent
550                                 MPI_Send(&num, 1, MPI_INT, 0, tag, MPI_COMM_WORLD);
551                         }
552                 }
553
554                 MPI_Barrier(MPI_COMM_WORLD); //make everyone wait - just in case
555 #else
556                 
557                 //loop through and create all the processes you want
558                 while (process != processors) {
559                         int pid = fork();
560                         
561                         if (pid > 0) {
562                                 processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
563                                 process++;
564                         }else if (pid == 0){
565                                 num = driver(outputFileName + toString(getpid()) + ".temp", files[process], accnos + toString(getpid()) + ".temp");
566                                 
567                                 //pass numSeqs to parent
568                                 ofstream out;
569                                 string tempFile = outputFileName + toString(getpid()) + ".num.temp";
570                                 m->openOutputFile(tempFile, out);
571                                 out << num << endl;
572                                 out.close();
573                                 
574                                 exit(0);
575                         }else { 
576                                 m->mothurOut("[ERROR]: unable to spawn the necessary processes."); m->mothurOutEndLine(); 
577                                 for (int i = 0; i < processIDS.size(); i++) { kill (processIDS[i], SIGINT); }
578                                 exit(0);
579                         }
580                 }
581                 
582                 //do my part
583                 num = driver(outputFileName, files[0], accnos);
584                 
585                 //force parent to wait until all the processes are done
586                 for (int i=0;i<processIDS.size();i++) { 
587                         int temp = processIDS[i];
588                         wait(&temp);
589                 }
590                 
591                 for (int i = 0; i < processIDS.size(); i++) {
592                         ifstream in;
593                         string tempFile =  outputFileName + toString(processIDS[i]) + ".num.temp";
594                         m->openInputFile(tempFile, in);
595                         if (!in.eof()) { int tempNum = 0; in >> tempNum; num += tempNum; }
596                         in.close(); remove(tempFile.c_str());
597                 }
598                 
599                 
600                 //append output files
601                 for(int i=0;i<processIDS[i];i++){
602                         m->appendFiles((outputFileName + toString(processIDS[i]) + ".temp"), outputFileName);
603                         remove((outputFileName + toString(processIDS[i]) + ".temp").c_str());
604                         
605                         m->appendFiles((accnos + toString(processIDS[i]) + ".temp"), accnos);
606                         remove((accnos + toString(processIDS[i]) + ".temp").c_str());
607                 }
608 #endif          
609                 //get rid of the file pieces.
610                 for (int i = 0; i < files.size(); i++) { remove(files[i].c_str()); }
611                 
612                 return num;     
613         }
614         catch(exception& e) {
615                 m->errorOut(e, "ChimeraUchimeCommand", "createProcesses");
616                 exit(1);
617         }
618 }
619
620 /**************************************************************************************************/
621