]> git.donarmstrong.com Git - mothur.git/blob - chimeracheckcommand.cpp
added compile time default path
[mothur.git] / chimeracheckcommand.cpp
1 /*
2  *  chimeracheckcommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 3/31/10.
6  *  Copyright 2010 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "chimeracheckcommand.h"
11 #include "chimeracheckrdp.h"
12
13 //***************************************************************************************************************
14
15 ChimeraCheckCommand::ChimeraCheckCommand(string option)  {
16         try {
17                 abort = false;
18                 
19                 //allow user to run help
20                 if(option == "help") { help(); abort = true; }
21                 
22                 else {
23                         //valid paramters for this command
24                         string Array[] =  {"fasta","processors","increment","template","ksize","svg", "name","outputdir","inputdir" };
25                         vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
26                         
27                         OptionParser parser(option);
28                         map<string,string> parameters = parser.getParameters();
29                         
30                         ValidParameters validParameter;
31                         map<string,string>::iterator it;
32                         
33                         //check to make sure all parameters are valid for command
34                         for (it = parameters.begin(); it != parameters.end(); it++) { 
35                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
36                         }
37                         
38                         //if the user changes the input directory command factory will send this info to us in the output parameter 
39                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
40                         if (inputDir == "not found"){   inputDir = "";          }
41                         else {
42                                 it = parameters.find("template");
43                                 //user has given a template file
44                                 if(it != parameters.end()){ 
45                                         string path = hasPath(it->second);
46                                         //if the user has not given a path then, add inputdir. else leave path alone.
47                                         if (path == "") {       parameters["template"] = inputDir + it->second;         }
48                                 }
49                         }
50                         
51                         //check for required parameters
52                         fastafile = validParameter.validFile(parameters, "fasta", false);
53                         if (fastafile == "not found") { fastafile = ""; m->mothurOut("fasta is a required parameter for the chimera.check command."); m->mothurOutEndLine(); abort = true;  }
54                         else { 
55                                 splitAtDash(fastafile, fastaFileNames);
56                                 
57                                 //go through files and make sure they are good, if not, then disregard them
58                                 for (int i = 0; i < fastaFileNames.size(); i++) {
59                                         if (inputDir != "") {
60                                                 string path = hasPath(fastaFileNames[i]);
61                                                 //if the user has not given a path then, add inputdir. else leave path alone.
62                                                 if (path == "") {       fastaFileNames[i] = inputDir + fastaFileNames[i];               }
63                                         }
64         
65                                         int ableToOpen;
66                                         ifstream in;
67                                         
68                                         #ifdef USE_MPI  
69                                                 int pid;
70                                                 MPI_Comm_size(MPI_COMM_WORLD, &processors); //set processors to the number of mpi processes running
71                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
72                                 
73                                                 if (pid == 0) {
74                                         #endif
75
76                                         ableToOpen = openInputFile(fastaFileNames[i], in, "noerror");
77                                 
78                                         //if you can't open it, try default location
79                                         if (ableToOpen == 1) {
80                                                 if (m->getDefaultPath() != "") { //default path is set
81                                                         string tryPath = m->getDefaultPath() + getSimpleName(fastaFileNames[i]);
82                                                         m->mothurOut("Unable to open " + fastaFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
83                                                         ableToOpen = openInputFile(tryPath, in, "noerror");
84                                                         fastaFileNames[i] = tryPath;
85                                                 }
86                                         }
87                                         in.close();
88                                         
89                                         #ifdef USE_MPI  
90                                                         for (int j = 1; j < processors; j++) {
91                                                                 MPI_Send(&ableToOpen, 1, MPI_INT, j, 2001, MPI_COMM_WORLD); 
92                                                         }
93                                                 }else{
94                                                         MPI_Status status;
95                                                         MPI_Recv(&ableToOpen, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
96                                                 }
97                                                 
98                                         #endif
99
100                                         if (ableToOpen == 1) { 
101                                                 m->mothurOut("Unable to open " + fastaFileNames[i] +". It will be disregarded."); m->mothurOutEndLine(); 
102                                                 //erase from file list
103                                                 fastaFileNames.erase(fastaFileNames.begin()+i);
104                                                 i--;
105                                         }
106                                 }
107                                 
108                                 //make sure there is at least one valid file left
109                                 if (fastaFileNames.size() == 0) { m->mothurOut("no valid files."); m->mothurOutEndLine(); abort = true; }
110                         }
111                         
112                         //if the user changes the output directory command factory will send this info to us in the output parameter 
113                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = ""; }
114
115                         templatefile = validParameter.validFile(parameters, "template", true);
116                         if (templatefile == "not open") { abort = true; }
117                         else if (templatefile == "not found") { templatefile = "";  m->mothurOut("template is a required parameter for the chimera.check command."); m->mothurOutEndLine(); abort = true;  }    
118                         
119                         namefile = validParameter.validFile(parameters, "name", false);
120                         if (namefile == "not found") { namefile = ""; }
121                         else { 
122                                 splitAtDash(namefile, nameFileNames);
123                                 
124                                 //go through files and make sure they are good, if not, then disregard them
125                                 for (int i = 0; i < nameFileNames.size(); i++) {
126                                         if (inputDir != "") {
127                                                 string path = hasPath(nameFileNames[i]);
128                                                 //if the user has not given a path then, add inputdir. else leave path alone.
129                                                 if (path == "") {       nameFileNames[i] = inputDir + nameFileNames[i];         }
130                                         }
131         
132                                         int ableToOpen;
133                                         ifstream in;
134                                         
135                                         #ifdef USE_MPI  
136                                                 int pid;
137                                                 MPI_Comm_size(MPI_COMM_WORLD, &processors); //set processors to the number of mpi processes running
138                                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
139                                 
140                                                 if (pid == 0) {
141                                         #endif
142
143                                         ableToOpen = openInputFile(nameFileNames[i], in, "noerror");
144                                 
145                                         //if you can't open it, try default location
146                                         if (ableToOpen == 1) {
147                                                 if (m->getDefaultPath() != "") { //default path is set
148                                                         string tryPath = m->getDefaultPath() + getSimpleName(nameFileNames[i]);
149                                                         m->mothurOut("Unable to open " + nameFileNames[i] + ". Trying default " + tryPath); m->mothurOutEndLine();
150                                                         ableToOpen = openInputFile(tryPath, in, "noerror");
151                                                         nameFileNames[i] = tryPath;
152                                                 }
153                                         }
154                                         in.close();
155                                         
156                                         #ifdef USE_MPI  
157                                                         for (int j = 1; j < processors; j++) {
158                                                                 MPI_Send(&ableToOpen, 1, MPI_INT, j, 2001, MPI_COMM_WORLD); 
159                                                         }
160                                                 }else{
161                                                         MPI_Status status;
162                                                         MPI_Recv(&ableToOpen, 1, MPI_INT, 0, 2001, MPI_COMM_WORLD, &status);
163                                                 }
164                                                 
165                                         #endif
166
167                                         if (ableToOpen == 1) { 
168                                                 m->mothurOut("Unable to open " + nameFileNames[i] + ". It will be disregarded."); m->mothurOutEndLine(); 
169                                                 //erase from file list
170                                                 nameFileNames.erase(nameFileNames.begin()+i);
171                                                 i--;
172                                         }
173                                         
174                                 }
175                                 
176                                 //make sure there is at least one valid file left
177                                 if (nameFileNames.size() != 0) {
178                                         if (nameFileNames.size() != fastaFileNames.size()) { 
179                                                  m->mothurOut("Different number of valid name files and fasta files, aborting command."); m->mothurOutEndLine(); 
180                                                  abort = true;
181                                         }
182                                 }
183                         }
184
185                         string temp = validParameter.validFile(parameters, "processors", false);                if (temp == "not found") { temp = "1"; }
186                         convert(temp, processors);
187                         
188                         temp = validParameter.validFile(parameters, "ksize", false);                    if (temp == "not found") { temp = "7"; }
189                         convert(temp, ksize);
190                         
191                         temp = validParameter.validFile(parameters, "svg", false);                              if (temp == "not found") { temp = "F"; }
192                         svg = isTrue(temp);
193                         if (nameFileNames.size() != 0) { svg = true; }
194                         
195                         temp = validParameter.validFile(parameters, "increment", false);                if (temp == "not found") { temp = "10"; }
196                         convert(temp, increment);                       
197                 }
198         }
199         catch(exception& e) {
200                 m->errorOut(e, "ChimeraCheckCommand", "ChimeraCheckCommand");
201                 exit(1);
202         }
203 }
204 //**********************************************************************************************************************
205
206 void ChimeraCheckCommand::help(){
207         try {
208         
209                 m->mothurOut("The chimera.check command reads a fastafile and templatefile and outputs potentially chimeric sequences.\n");
210                 m->mothurOut("This command was created using the algorythms described in CHIMERA_CHECK version 2.7 written by Niels Larsen. \n");
211                 m->mothurOut("The chimera.check command parameters are fasta, template, processors, ksize, increment, svg and name.\n");
212                 m->mothurOut("The fasta parameter allows you to enter the fasta file containing your potentially chimeric sequences, and is required. \n");
213                 m->mothurOut("You may enter multiple fasta files by separating their names with dashes. ie. fasta=abrecovery.fasta-amzon.fasta \n");
214                 m->mothurOut("The template parameter allows you to enter a template file containing known non-chimeric sequences, and is required. \n");
215                 m->mothurOut("The processors parameter allows you to specify how many processors you would like to use.  The default is 1. \n");
216                 #ifdef USE_MPI
217                 m->mothurOut("When using MPI, the processors parameter is set to the number of MPI processes running. \n");
218                 #endif
219                 m->mothurOut("The increment parameter allows you to specify how far you move each window while finding chimeric sequences, default is 10.\n");
220                 m->mothurOut("The ksize parameter allows you to input kmersize, default is 7. \n");
221                 m->mothurOut("The svg parameter allows you to specify whether or not you would like a svg file outputted for each query sequence, default is False.\n");
222                 m->mothurOut("The name parameter allows you to enter a file containing names of sequences you would like .svg files for.\n");
223                 m->mothurOut("You may enter multiple name files by separating their names with dashes. ie. fasta=abrecovery.svg.names-amzon.svg.names \n");
224                 m->mothurOut("The chimera.check command should be in the following format: \n");
225                 m->mothurOut("chimera.check(fasta=yourFastaFile, template=yourTemplateFile, processors=yourProcessors, ksize=yourKmerSize) \n");
226                 m->mothurOut("Example: chimera.check(fasta=AD.fasta, template=core_set_aligned,imputed.fasta, processors=4, ksize=8) \n");
227                 m->mothurOut("Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFastaFile).\n\n");     
228         }
229         catch(exception& e) {
230                 m->errorOut(e, "ChimeraCheckCommand", "help");
231                 exit(1);
232         }
233 }
234
235 //***************************************************************************************************************
236
237 ChimeraCheckCommand::~ChimeraCheckCommand(){    /*      do nothing      */      }
238
239 //***************************************************************************************************************
240
241 int ChimeraCheckCommand::execute(){
242         try{
243                 
244                 if (abort == true) { return 0; }
245                 
246                 for (int i = 0; i < fastaFileNames.size(); i++) {
247                                 
248                         m->mothurOut("Checking sequences from " + fastaFileNames[i] + " ..." ); m->mothurOutEndLine();
249                         
250                         int start = time(NULL); 
251                         
252                         string thisNameFile = "";
253                         if (nameFileNames.size() != 0) { thisNameFile = nameFileNames[i]; }
254                         
255                         chimera = new ChimeraCheckRDP(fastaFileNames[i], templatefile, thisNameFile, svg, increment, ksize, outputDir);                 
256
257                         if (m->control_pressed) { delete chimera;       return 0;       }
258                         
259                         string outputFileName = outputDir + getRootName(getSimpleName(fastaFileNames[i]))  + "chimeracheck.chimeras";
260                         outputNames.push_back(outputFileName);
261                         
262                 #ifdef USE_MPI
263                 
264                                 int pid, end, numSeqsPerProcessor; 
265                                 int tag = 2001;
266                                 vector<long> MPIPos;
267                                 
268                                 MPI_Status status; 
269                                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
270                                 MPI_Comm_size(MPI_COMM_WORLD, &processors); 
271
272                                 MPI_File inMPI;
273                                 MPI_File outMPI;
274                                                         
275                                 int outMode=MPI_MODE_CREATE|MPI_MODE_WRONLY; 
276                                 int inMode=MPI_MODE_RDONLY; 
277                                                         
278                                 char outFilename[1024];
279                                 strcpy(outFilename, outputFileName.c_str());
280                         
281                                 char inFileName[1024];
282                                 strcpy(inFileName, fastaFileNames[i].c_str());
283
284                                 MPI_File_open(MPI_COMM_WORLD, inFileName, inMode, MPI_INFO_NULL, &inMPI);  //comm, filename, mode, info, filepointer
285                                 MPI_File_open(MPI_COMM_WORLD, outFilename, outMode, MPI_INFO_NULL, &outMPI);
286                                 
287                                 if (m->control_pressed) {  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);  for (int j = 0; j < outputNames.size(); j++) {    remove(outputNames[j].c_str()); } delete chimera; return 0;  }
288                                 
289                                 if (pid == 0) { //you are the root process 
290                                         MPIPos = setFilePosFasta(fastaFileNames[i], numSeqs); //fills MPIPos, returns numSeqs
291                                         
292                                         //send file positions to all processes
293                                         for(int j = 1; j < processors; j++) { 
294                                                 MPI_Send(&numSeqs, 1, MPI_INT, j, tag, MPI_COMM_WORLD);
295                                                 MPI_Send(&MPIPos[0], (numSeqs+1), MPI_LONG, j, tag, MPI_COMM_WORLD);
296                                         }       
297                                         
298                                         //figure out how many sequences you have to align
299                                         numSeqsPerProcessor = numSeqs / processors;
300                                         int startIndex =  pid * numSeqsPerProcessor;
301                                         if(pid == (processors - 1)){    numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor;      }
302                                         
303                                 
304                                         //align your part
305                                         driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, MPIPos);
306                                         
307                                         if (m->control_pressed) {  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);  for (int j = 0; j < outputNames.size(); j++) {    remove(outputNames[j].c_str()); }   delete chimera; return 0;  }
308                                         
309                                         //wait on chidren
310                                         for(int j = 1; j < processors; j++) { 
311                                                 char buf[4];
312                                                 MPI_Recv(buf, 4, MPI_CHAR, j, tag, MPI_COMM_WORLD, &status); 
313                                         }
314                                 }else{ //you are a child process
315                                         MPI_Recv(&numSeqs, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
316                                         MPIPos.resize(numSeqs+1);
317                                         MPI_Recv(&MPIPos[0], (numSeqs+1), MPI_LONG, 0, tag, MPI_COMM_WORLD, &status);
318                                         
319                                         //figure out how many sequences you have to align
320                                         numSeqsPerProcessor = numSeqs / processors;
321                                         int startIndex =  pid * numSeqsPerProcessor;
322                                         if(pid == (processors - 1)){    numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor;      }
323                                         
324                                         //align your part
325                                         driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, MPIPos);
326                                         
327                                         if (m->control_pressed) {  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);   for (int j = 0; j < outputNames.size(); j++) {   remove(outputNames[j].c_str()); }  delete chimera; return 0;  }
328                                         
329                                         //tell parent you are done.
330                                         char buf[4];
331                                         strcpy(buf, "done"); 
332                                         MPI_Send(buf, 4, MPI_CHAR, 0, tag, MPI_COMM_WORLD);
333                                 }
334                                 
335                                 //close files 
336                                 MPI_File_close(&inMPI);
337                                 MPI_File_close(&outMPI);
338                                 MPI_Barrier(MPI_COMM_WORLD); //make everyone wait - just in case
339                 #else
340                         
341                         //break up file
342                         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
343                                 if(processors == 1){
344                                         ifstream inFASTA;
345                                         openInputFile(fastaFileNames[i], inFASTA);
346                                         getNumSeqs(inFASTA, numSeqs);
347                                         inFASTA.close();
348                                         
349                                         lines.push_back(new linePair(0, numSeqs));
350                                         
351                                         driver(lines[0], outputFileName, fastaFileNames[i]);
352                                         
353                                         if (m->control_pressed) { 
354                                                 for (int j = 0; j < outputNames.size(); j++) {  remove(outputNames[j].c_str()); } 
355                                                 for (int j = 0; j < lines.size(); j++) {  delete lines[j];  }  lines.clear();
356                                                 delete chimera;
357                                                 return 0;
358                                         }
359                                                                         
360                                 }else{
361                                         vector<unsigned long int> positions;
362                                         processIDS.resize(0);
363                                         
364                                         ifstream inFASTA;
365                                         openInputFile(fastaFileNames[i], inFASTA);
366                                         
367                                         string input;
368                                         while(!inFASTA.eof()){
369                                                 input = getline(inFASTA);
370                                                 if (input.length() != 0) {
371                                                         if(input[0] == '>'){    unsigned long int pos = inFASTA.tellg(); positions.push_back(pos - input.length() - 1); }
372                                                 }
373                                         }
374                                         inFASTA.close();
375                                         
376                                         numSeqs = positions.size();
377                                         
378                                         int numSeqsPerProcessor = numSeqs / processors;
379                                         
380                                         for (int j = 0; j < processors; j++) {
381                                                 unsigned long int startPos = positions[ j * numSeqsPerProcessor ];
382                                                 if(j == processors - 1){
383                                                         numSeqsPerProcessor = numSeqs - j * numSeqsPerProcessor;
384                                                 }
385                                                 lines.push_back(new linePair(startPos, numSeqsPerProcessor));
386                                         }
387                                         
388                                         
389                                         createProcesses(outputFileName, fastaFileNames[i]); 
390                                 
391                                         rename((outputFileName + toString(processIDS[0]) + ".temp").c_str(), outputFileName.c_str());
392                                                 
393                                         //append output files
394                                         for(int j=1;j<processors;j++){
395                                                 appendFiles((outputFileName + toString(processIDS[j]) + ".temp"), outputFileName);
396                                                 remove((outputFileName + toString(processIDS[j]) + ".temp").c_str());
397                                         }
398                                         
399                                         if (m->control_pressed) { 
400                                                 for (int j = 0; j < outputNames.size(); j++) {  remove(outputNames[j].c_str()); } 
401                                                 for (int j = 0; j < lines.size(); j++) {  delete lines[j];  }  lines.clear();
402                                                 delete chimera;
403                                                 return 0;
404                                         }
405                                 }
406
407                         #else
408                                 ifstream inFASTA;
409                                 openInputFile(fastaFileNames[i], inFASTA);
410                                 getNumSeqs(inFASTA, numSeqs);
411                                 inFASTA.close();
412                                 lines.push_back(new linePair(0, numSeqs));
413                                 
414                                 driver(lines[0], outputFileName, fastaFileNames[i]);
415                                 
416                                 if (m->control_pressed) { 
417                                                 for (int j = 0; j < lines.size(); j++) {  delete lines[j];  }  lines.clear();
418                                                 for (int j = 0; j < outputNames.size(); j++) {  remove(outputNames[j].c_str()); } 
419                                                 delete chimera;
420                                                 return 0;
421                                 }
422                         #endif
423                 #endif          
424                         delete chimera;
425                         for (int j = 0; j < lines.size(); j++) {  delete lines[j];  }  lines.clear();
426                         
427                         m->mothurOutEndLine(); m->mothurOut("This method does not determine if a sequence is chimeric, but allows you to make that determination based on the IS values."); m->mothurOutEndLine(); 
428                         m->mothurOutEndLine(); m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(numSeqs) + " sequences."); m->mothurOutEndLine(); m->mothurOutEndLine();
429
430                 }
431                 
432                 m->mothurOutEndLine();
433                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
434                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }       
435                 m->mothurOutEndLine();
436         
437                 return 0;
438                 
439         }
440         catch(exception& e) {
441                 m->errorOut(e, "ChimeraCheckCommand", "execute");
442                 exit(1);
443         }
444 }
445 //**********************************************************************************************************************
446
447 int ChimeraCheckCommand::driver(linePair* line, string outputFName, string filename){
448         try {
449                 ofstream out;
450                 openOutputFile(outputFName, out);
451                 
452                 ofstream out2;
453                 
454                 ifstream inFASTA;
455                 openInputFile(filename, inFASTA);
456
457                 inFASTA.seekg(line->start);
458                 
459                 for(int i=0;i<line->numSeqs;i++){
460                 
461                         if (m->control_pressed) {       return 1;       }
462                 
463                         Sequence* candidateSeq = new Sequence(inFASTA);  gobble(inFASTA);
464                                 
465                         if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
466                                 //find chimeras
467                                 chimera->getChimeras(candidateSeq);
468                                 
469                                 if (m->control_pressed) {       delete candidateSeq; return 1;  }
470         
471                                 //print results
472                                 chimera->print(out, out2);
473                         }
474                         delete candidateSeq;
475                         
476                         //report progress
477                         if((i+1) % 100 == 0){   m->mothurOut("Processing sequence: " + toString(i+1)); m->mothurOutEndLine();           }
478                 }
479                 //report progress
480                 if((line->numSeqs) % 100 != 0){ m->mothurOut("Processing sequence: " + toString(line->numSeqs)); m->mothurOutEndLine();         }
481                 
482                 out.close();
483                 inFASTA.close();
484                                 
485                 return 0;
486         }
487         catch(exception& e) {
488                 m->errorOut(e, "ChimeraCheckCommand", "driver");
489                 exit(1);
490         }
491 }
492 //**********************************************************************************************************************
493 #ifdef USE_MPI
494 int ChimeraCheckCommand::driverMPI(int start, int num, MPI_File& inMPI, MPI_File& outMPI, vector<long>& MPIPos){
495         try {
496                 MPI_File outAccMPI;
497                 MPI_Status status; 
498                 int pid;
499                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
500                 
501                 for(int i=0;i<num;i++){
502                         
503                         if (m->control_pressed) { return 0; }
504                         
505                         //read next sequence
506                         int length = MPIPos[start+i+1] - MPIPos[start+i];
507         
508                         char* buf4 = new char[length];
509                         MPI_File_read_at(inMPI, MPIPos[start+i], buf4, length, MPI_CHAR, &status);
510                         
511                         string tempBuf = buf4;
512                         if (tempBuf.length() > length) { tempBuf = tempBuf.substr(0, length);  }
513                         istringstream iss (tempBuf,istringstream::in);
514                         delete buf4;
515
516                         Sequence* candidateSeq = new Sequence(iss);  gobble(iss);
517                                 
518                         if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
519                                 //find chimeras
520                                 chimera->getChimeras(candidateSeq);
521                                         
522                                 //print results
523                                 chimera->print(outMPI, outAccMPI);
524                         }
525                         delete candidateSeq;
526                         
527                         //report progress
528                         if((i+1) % 100 == 0){  cout << "Processing sequence: " << (i+1) << endl;        m->mothurOutJustToLog("Processing sequence: " + toString(i+1) + "\n");          }
529                 }
530                 //report progress
531                 if(num % 100 != 0){             cout << "Processing sequence: " << num << endl; m->mothurOutJustToLog("Processing sequence: " + toString(num) + "\n");  }
532                 
533                 return 0;
534         }
535         catch(exception& e) {
536                 m->errorOut(e, "ChimeraCheckCommand", "driverMPI");
537                 exit(1);
538         }
539 }
540 #endif
541
542 /**************************************************************************************************/
543
544 int ChimeraCheckCommand::createProcesses(string outputFileName, string filename) {
545         try {
546 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
547                 int process = 0;
548                 //              processIDS.resize(0);
549                 
550                 //loop through and create all the processes you want
551                 while (process != processors) {
552                         int pid = fork();
553                         
554                         if (pid > 0) {
555                                 processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
556                                 process++;
557                         }else if (pid == 0){
558                                 driver(lines[process], outputFileName + toString(getpid()) + ".temp", filename);
559                                 exit(0);
560                         }else { m->mothurOut("unable to spawn the necessary processes."); m->mothurOutEndLine(); exit(0); }
561                 }
562                 
563                 //force parent to wait until all the processes are done
564                 for (int i=0;i<processors;i++) { 
565                         int temp = processIDS[i];
566                         wait(&temp);
567                 }
568                 
569                 return 0;
570 #endif          
571         }
572         catch(exception& e) {
573                 m->errorOut(e, "ChimeraCheckCommand", "createProcesses");
574                 exit(1);
575         }
576 }
577 /**************************************************************************************************/
578
579