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