]> git.donarmstrong.com Git - mothur.git/blob - chimerapintailcommand.cpp
made classifier faster
[mothur.git] / chimerapintailcommand.cpp
1 /*
2  *  chimerapintailcommand.cpp
3  *  Mothur
4  *
5  *  Created by westcott on 4/1/10.
6  *  Copyright 2010 Schloss Lab. All rights reserved.
7  *
8  */
9
10 #include "chimerapintailcommand.h"
11 #include "pintail.h"
12
13 //***************************************************************************************************************
14
15 ChimeraPintailCommand::ChimeraPintailCommand(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","filter","processors","window" ,"increment","template","conservation","quantile","mask","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                                 string path;
43                                 it = parameters.find("fasta");
44                                 //user has given a template file
45                                 if(it != parameters.end()){ 
46                                         path = hasPath(it->second);
47                                         //if the user has not given a path then, add inputdir. else leave path alone.
48                                         if (path == "") {       parameters["fasta"] = inputDir + it->second;            }
49                                 }
50                                 
51                                 it = parameters.find("template");
52                                 //user has given a template file
53                                 if(it != parameters.end()){ 
54                                         path = hasPath(it->second);
55                                         //if the user has not given a path then, add inputdir. else leave path alone.
56                                         if (path == "") {       parameters["template"] = inputDir + it->second;         }
57                                 }
58                                 
59                                 it = parameters.find("conservation");
60                                 //user has given a template file
61                                 if(it != parameters.end()){ 
62                                         path = hasPath(it->second);
63                                         //if the user has not given a path then, add inputdir. else leave path alone.
64                                         if (path == "") {       parameters["conservation"] = inputDir + it->second;             }
65                                 }
66                                 
67                                 it = parameters.find("quantile");
68                                 //user has given a template file
69                                 if(it != parameters.end()){ 
70                                         path = hasPath(it->second);
71                                         //if the user has not given a path then, add inputdir. else leave path alone.
72                                         if (path == "") {       parameters["quantile"] = inputDir + it->second;         }
73                                 }
74                         }
75
76                         
77                         //check for required parameters
78                         fastafile = validParameter.validFile(parameters, "fasta", true);
79                         if (fastafile == "not open") { abort = true; }
80                         else if (fastafile == "not found") { fastafile = ""; m->mothurOut("fasta is a required parameter for the chimera.pintail command."); m->mothurOutEndLine(); abort = true;  }    
81                         
82                         //if the user changes the output directory command factory will send this info to us in the output parameter 
83                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  
84                                 outputDir = ""; 
85                                 outputDir += hasPath(fastafile); //if user entered a file with a path then preserve it  
86                         }
87
88                         templatefile = validParameter.validFile(parameters, "template", true);
89                         if (templatefile == "not open") { abort = true; }
90                         else if (templatefile == "not found") { templatefile = "";  m->mothurOut("template is a required parameter for the chimera.pintail command."); m->mothurOutEndLine(); abort = true;  }
91                         
92                         consfile = validParameter.validFile(parameters, "conservation", true);
93                         if (consfile == "not open") { abort = true; }
94                         else if (consfile == "not found") { consfile = "";  }   
95                         
96                         quanfile = validParameter.validFile(parameters, "quantile", true);
97                         if (quanfile == "not open") { abort = true; }
98                         else if (quanfile == "not found") { quanfile = "";  }
99                         
100                         maskfile = validParameter.validFile(parameters, "mask", false);
101                         if (maskfile == "not found") { maskfile = "";  }        
102                         else if (maskfile != "default")  { 
103                                 if (inputDir != "") {
104                                         string path = hasPath(maskfile);
105                                         //if the user has not given a path then, add inputdir. else leave path alone.
106                                         if (path == "") {       maskfile = inputDir + maskfile;         }
107                                 }
108
109                                 ifstream in;
110                                 int     ableToOpen = openInputFile(maskfile, in);
111                                 if (ableToOpen == 1) { abort = true; }
112                                 in.close();
113                         }
114                                                 
115                         string temp;
116                         temp = validParameter.validFile(parameters, "filter", false);                   if (temp == "not found") { temp = "F"; }
117                         filter = isTrue(temp);
118                         
119                         temp = validParameter.validFile(parameters, "processors", false);               if (temp == "not found") { temp = "1"; }
120                         convert(temp, processors);
121                         
122                         temp = validParameter.validFile(parameters, "window", false);                   if (temp == "not found") { temp = "0"; }
123                         convert(temp, window);
124                         
125                         temp = validParameter.validFile(parameters, "increment", false);                if (temp == "not found") { temp = "25"; }
126                         convert(temp, increment);
127                 }
128         }
129         catch(exception& e) {
130                 m->errorOut(e, "ChimeraPintailCommand", "ChimeraPintailCommand");
131                 exit(1);
132         }
133 }
134 //**********************************************************************************************************************
135
136 void ChimeraPintailCommand::help(){
137         try {
138         
139                 m->mothurOut("The chimera.pintail command reads a fastafile and templatefile and outputs potentially chimeric sequences.\n");
140                 m->mothurOut("This command was created using the algorythms described in the 'At Least 1 in 20 16S rRNA Sequence Records Currently Held in the Public Repositories is Estimated To Contain Substantial Anomalies' paper by Kevin E. Ashelford 1, Nadia A. Chuzhanova 3, John C. Fry 1, Antonia J. Jones 2 and Andrew J. Weightman 1.\n");
141                 m->mothurOut("The chimera.pintail command parameters are fasta, template, filter, mask, processors, window, increment, conservation and quantile.\n");
142                 m->mothurOut("The fasta parameter allows you to enter the fasta file containing your potentially chimeric sequences, and is required. \n");
143                 m->mothurOut("The template parameter allows you to enter a template file containing known non-chimeric sequences, and is required. \n");
144                 m->mothurOut("The filter parameter allows you to specify if you would like to apply a vertical and 50% soft filter. \n");
145                 m->mothurOut("The mask parameter allows you to specify a file containing one sequence you wish to use as a mask for the your sequences, by default no mask is applied.  You can apply an ecoli mask by typing, mask=default. \n");
146                 m->mothurOut("The processors parameter allows you to specify how many processors you would like to use.  The default is 1. \n");
147                 #ifdef USE_MPI
148                 m->mothurOut("When using MPI, the processors parameter is set to the number of MPI processes running. \n");
149                 #endif
150                 m->mothurOut("The window parameter allows you to specify the window size for searching for chimeras, default=300. \n");
151                 m->mothurOut("The increment parameter allows you to specify how far you move each window while finding chimeric sequences, default=25.\n");
152                 m->mothurOut("The conservation parameter allows you to enter a frequency file containing the highest bases frequency at each place in the alignment.\n");
153                 m->mothurOut("The quantile parameter allows you to enter a file containing quantiles for a template files sequences, if you use the filter the quantile file generated becomes unique to the fasta file you used.\n");
154                 m->mothurOut("The chimera.pintail command should be in the following format: \n");
155                 m->mothurOut("chimera.seqs(fasta=yourFastaFile, filter=yourFilter, correction=yourCorrection, processors=yourProcessors, method=bellerophon) \n");
156                 m->mothurOut("Example: chimera.seqs(fasta=AD.align, filter=True, correction=true, method=bellerophon, window=200) \n");
157                 m->mothurOut("Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFastaFile).\n\n");     
158         }
159         catch(exception& e) {
160                 m->errorOut(e, "ChimeraPintailCommand", "help");
161                 exit(1);
162         }
163 }
164
165 //***************************************************************************************************************
166
167 ChimeraPintailCommand::~ChimeraPintailCommand(){        /*      do nothing      */      }
168
169 //***************************************************************************************************************
170
171 int ChimeraPintailCommand::execute(){
172         try{
173                 
174                 if (abort == true) { return 0; }
175                 
176                 int start = time(NULL); 
177                 
178                 //set user options
179                 if (maskfile == "default") { m->mothurOut("I am using the default 236627 EU009184.1 Shigella dysenteriae str. FBD013."); m->mothurOutEndLine();  }
180                 
181                 chimera = new Pintail(fastafile, templatefile, filter, processors, maskfile, consfile, quanfile, window, increment, outputDir);
182                 
183                 string outputFileName, accnosFileName;
184                 if (maskfile != "") {
185                         outputFileName = outputDir + getRootName(getSimpleName(fastafile)) + maskfile + ".pintail.chimeras";
186                         accnosFileName = outputDir + getRootName(getSimpleName(fastafile)) + maskfile + ".pintail.accnos";
187                 }else {
188                         outputFileName = outputDir + getRootName(getSimpleName(fastafile))  + "pintail.chimeras";
189                         accnosFileName = outputDir + getRootName(getSimpleName(fastafile))  + "pintail.accnos";
190                 }
191                 bool hasAccnos = true;
192                 
193                 if (m->control_pressed) { delete chimera;       return 0;       }
194                 
195                 if (chimera->getUnaligned()) { 
196                         m->mothurOut("Your template sequences are different lengths, please correct."); m->mothurOutEndLine(); 
197                         delete chimera;
198                         return 0; 
199                 }
200                 templateSeqsLength = chimera->getLength();
201         
202         #ifdef USE_MPI
203                 int pid, end, numSeqsPerProcessor; 
204                         int tag = 2001;
205                         vector<long> MPIPos;
206                         MPIWroteAccnos = false;
207                         
208                         MPI_Status status; 
209                         MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
210                         MPI_Comm_size(MPI_COMM_WORLD, &processors); 
211
212                         MPI_File inMPI;
213                         MPI_File outMPI;
214                         MPI_File outMPIAccnos;
215                         
216                         int outMode=MPI_MODE_CREATE|MPI_MODE_WRONLY; 
217                         int inMode=MPI_MODE_RDONLY; 
218                         
219                         //char* outFilename = new char[outputFileName.length()];
220                         //memcpy(outFilename, outputFileName.c_str(), outputFileName.length());
221                         
222                         char outFilename[1024];
223                         strcpy(outFilename, outputFileName.c_str());
224                         
225                         //char* outAccnosFilename = new char[accnosFileName.length()];
226                         //memcpy(outAccnosFilename, accnosFileName.c_str(), accnosFileName.length());
227                         
228                         char outAccnosFilename[1024];
229                         strcpy(outAccnosFilename, accnosFileName.c_str());
230
231                         //char* inFileName = new char[fastafile.length()];
232                         //memcpy(inFileName, fastafile.c_str(), fastafile.length());
233                         
234                         char inFileName[1024];
235                         strcpy(inFileName, fastafile.c_str());
236
237                         MPI_File_open(MPI_COMM_WORLD, inFileName, inMode, MPI_INFO_NULL, &inMPI);  //comm, filename, mode, info, filepointer
238                         MPI_File_open(MPI_COMM_WORLD, outFilename, outMode, MPI_INFO_NULL, &outMPI);
239                         MPI_File_open(MPI_COMM_WORLD, outAccnosFilename, outMode, MPI_INFO_NULL, &outMPIAccnos);
240                         
241                         //delete inFileName;
242                         //delete outFilename;
243                         //delete outAccnosFilename;
244
245                         if (m->control_pressed) {  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);   MPI_File_close(&outMPIAccnos);  delete chimera; return 0;  }
246
247                         if (pid == 0) { //you are the root process 
248                                                         
249                                 MPIPos = setFilePosFasta(fastafile, numSeqs); //fills MPIPos, returns numSeqs
250                                 
251                                 //send file positions to all processes
252                                 MPI_Bcast(&numSeqs, 1, MPI_INT, 0, MPI_COMM_WORLD);  //send numSeqs
253                                 MPI_Bcast(&MPIPos[0], (numSeqs+1), MPI_LONG, 0, MPI_COMM_WORLD); //send file pos        
254                                 
255                                 //figure out how many sequences you have to align
256                                 numSeqsPerProcessor = numSeqs / processors;
257                                 if(pid == (processors - 1)){    numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor;      }
258                                 int startIndex =  pid * numSeqsPerProcessor;
259                         
260                                 //align your part
261                                 driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, outMPIAccnos, MPIPos);
262                                 
263                                 if (m->control_pressed) {  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);   MPI_File_close(&outMPIAccnos);  remove(outputFileName.c_str());  remove(accnosFileName.c_str());  delete chimera; return 0;  }
264                                 
265                                 for (int i = 1; i < processors; i++) {
266                                         bool tempResult;
267                                         MPI_Recv(&tempResult, 1, MPI_INT, i, tag, MPI_COMM_WORLD, &status);
268                                         if (tempResult != 0) { MPIWroteAccnos = true; }
269                                 }
270                         }else{ //you are a child process
271                                 MPI_Bcast(&numSeqs, 1, MPI_INT, 0, MPI_COMM_WORLD); //get numSeqs
272                                 MPIPos.resize(numSeqs+1);
273                                 MPI_Bcast(&MPIPos[0], (numSeqs+1), MPI_LONG, 0, MPI_COMM_WORLD); //get file positions
274                                 
275                                 //figure out how many sequences you have to align
276                                 numSeqsPerProcessor = numSeqs / processors;
277                                 if(pid == (processors - 1)){    numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor;      }
278                                 int startIndex =  pid * numSeqsPerProcessor;
279                                 
280                                 //align your part
281                                 driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, outMPIAccnos, MPIPos);
282                                 
283                                 if (m->control_pressed) {  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);   MPI_File_close(&outMPIAccnos);  delete chimera; return 0;  }
284
285                                 MPI_Send(&MPIWroteAccnos, 1, MPI_INT, 0, tag, MPI_COMM_WORLD); 
286                         }
287                         
288                         //close files 
289                         MPI_File_close(&inMPI);
290                         MPI_File_close(&outMPI);
291                         MPI_File_close(&outMPIAccnos);
292                         
293                         //delete accnos file if blank
294                         if (pid == 0) {
295                                 if (!MPIWroteAccnos) { 
296                                         //MPI_Info info;
297                                         //MPI_File_delete(outAccnosFilename, info);
298                                         hasAccnos = false;      
299                                         remove(accnosFileName.c_str()); 
300                                 }
301                         }
302
303         #else
304         
305                 //break up file
306                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
307                         if(processors == 1){
308                                 ifstream inFASTA;
309                                 openInputFile(fastafile, inFASTA);
310                                 numSeqs=count(istreambuf_iterator<char>(inFASTA),istreambuf_iterator<char>(), '>');
311                                 inFASTA.close();
312                                 
313                                 lines.push_back(new linePair(0, numSeqs));
314                                 
315                                 driver(lines[0], outputFileName, fastafile, accnosFileName);
316                                 
317                                 if (m->control_pressed) { 
318                                         remove(outputFileName.c_str()); 
319                                         remove(accnosFileName.c_str());
320                                         for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
321                                         delete chimera;
322                                         return 0;
323                                 }
324                                 
325                                 //delete accnos file if its blank 
326                                 if (isBlank(accnosFileName)) {  remove(accnosFileName.c_str());  hasAccnos = false; }
327                                                                 
328                         }else{
329                                 vector<int> positions;
330                                 processIDS.resize(0);
331                                 
332                                 ifstream inFASTA;
333                                 openInputFile(fastafile, inFASTA);
334                                 
335                                 string input;
336                                 while(!inFASTA.eof()){
337                                         input = getline(inFASTA);
338                                         if (input.length() != 0) {
339                                                 if(input[0] == '>'){    long int pos = inFASTA.tellg(); positions.push_back(pos - input.length() - 1);  }
340                                         }
341                                 }
342                                 inFASTA.close();
343                                 
344                                 numSeqs = positions.size();
345                                 
346                                 int numSeqsPerProcessor = numSeqs / processors;
347                                 
348                                 for (int i = 0; i < processors; i++) {
349                                         long int startPos = positions[ i * numSeqsPerProcessor ];
350                                         if(i == processors - 1){
351                                                 numSeqsPerProcessor = numSeqs - i * numSeqsPerProcessor;
352                                         }
353                                         lines.push_back(new linePair(startPos, numSeqsPerProcessor));
354                                 }
355                                 
356                                 
357                                 createProcesses(outputFileName, fastafile, accnosFileName); 
358                         
359                                 rename((outputFileName + toString(processIDS[0]) + ".temp").c_str(), outputFileName.c_str());
360                                         
361                                 //append output files
362                                 for(int i=1;i<processors;i++){
363                                         appendFiles((outputFileName + toString(processIDS[i]) + ".temp"), outputFileName);
364                                         remove((outputFileName + toString(processIDS[i]) + ".temp").c_str());
365                                 }
366                                 
367                                 vector<string> nonBlankAccnosFiles;
368                                 //delete blank accnos files generated with multiple processes
369                                 for(int i=0;i<processors;i++){  
370                                         if (!(isBlank(accnosFileName + toString(processIDS[i]) + ".temp"))) {
371                                                 nonBlankAccnosFiles.push_back(accnosFileName + toString(processIDS[i]) + ".temp");
372                                         }else { remove((accnosFileName + toString(processIDS[i]) + ".temp").c_str());  }
373                                 }
374                                 
375                                 //append accnos files
376                                 if (nonBlankAccnosFiles.size() != 0) { 
377                                         rename(nonBlankAccnosFiles[0].c_str(), accnosFileName.c_str());
378                                         
379                                         for (int h=1; h < nonBlankAccnosFiles.size(); h++) {
380                                                 appendFiles(nonBlankAccnosFiles[h], accnosFileName);
381                                                 remove(nonBlankAccnosFiles[h].c_str());
382                                         }
383                                 }else{ hasAccnos = false;  }
384                                 
385                                 if (m->control_pressed) { 
386                                         remove(outputFileName.c_str()); 
387                                         remove(accnosFileName.c_str());
388                                         for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
389                                         delete chimera;
390                                         return 0;
391                                 }
392                         }
393
394                 #else
395                         ifstream inFASTA;
396                         openInputFile(fastafile, inFASTA);
397                         numSeqs=count(istreambuf_iterator<char>(inFASTA),istreambuf_iterator<char>(), '>');
398                         inFASTA.close();
399                         lines.push_back(new linePair(0, numSeqs));
400                         
401                         driver(lines[0], outputFileName, fastafile, accnosFileName);
402                         
403                         if (m->control_pressed) { 
404                                         remove(outputFileName.c_str()); 
405                                         remove(accnosFileName.c_str());
406                                         for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
407                                         delete chimera;
408                                         return 0;
409                         }
410                         
411                         //delete accnos file if its blank 
412                         if (isBlank(accnosFileName)) {  remove(accnosFileName.c_str());  hasAccnos = false; }
413                 #endif
414                 
415         #endif  
416         
417                 delete chimera;
418                 for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
419                 
420                 m->mothurOutEndLine();
421                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
422                 m->mothurOut(outputFileName); m->mothurOutEndLine();    
423                 if (hasAccnos) {  m->mothurOut(accnosFileName); m->mothurOutEndLine();  }
424                 m->mothurOutEndLine();
425                 m->mothurOutEndLine(); m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(numSeqs) + " sequences."); m->mothurOutEndLine();
426                 
427                 return 0;
428                 
429         }
430         catch(exception& e) {
431                 m->errorOut(e, "ChimeraPintailCommand", "execute");
432                 exit(1);
433         }
434 }
435 //**********************************************************************************************************************
436
437 int ChimeraPintailCommand::driver(linePair* line, string outputFName, string filename, string accnos){
438         try {
439                 ofstream out;
440                 openOutputFile(outputFName, out);
441                 
442                 ofstream out2;
443                 openOutputFile(accnos, out2);
444                 
445                 ifstream inFASTA;
446                 openInputFile(filename, inFASTA);
447
448                 inFASTA.seekg(line->start);
449                 
450                 for(int i=0;i<line->numSeqs;i++){
451                 
452                         if (m->control_pressed) {       return 1;       }
453                 
454                         Sequence* candidateSeq = new Sequence(inFASTA);  gobble(inFASTA);
455                                 
456                         if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
457                                 
458                                 if (candidateSeq->getAligned().length() != templateSeqsLength)  {  //chimeracheck does not require seqs to be aligned
459                                         m->mothurOut(candidateSeq->getName() + " is not the same length as the template sequences. Skipping."); m->mothurOutEndLine();
460                                 }else{
461                                         //find chimeras
462                                         chimera->getChimeras(candidateSeq);
463                                         
464                                         if (m->control_pressed) {       delete candidateSeq; return 1;  }
465                 
466                                         //print results
467                                         chimera->print(out, out2);
468                                 }
469                         }
470                         delete candidateSeq;
471                         
472                         //report progress
473                         if((i+1) % 100 == 0){   m->mothurOut("Processing sequence: " + toString(i+1)); m->mothurOutEndLine();           }
474                 }
475                 //report progress
476                 if((line->numSeqs) % 100 != 0){ m->mothurOut("Processing sequence: " + toString(line->numSeqs)); m->mothurOutEndLine();         }
477                 
478                 out.close();
479                 out2.close();
480                 inFASTA.close();
481                                 
482                 return 0;
483         }
484         catch(exception& e) {
485                 m->errorOut(e, "ChimeraPintailCommand", "driver");
486                 exit(1);
487         }
488 }
489 //**********************************************************************************************************************
490 #ifdef USE_MPI
491 int ChimeraPintailCommand::driverMPI(int start, int num, MPI_File& inMPI, MPI_File& outMPI, MPI_File& outAccMPI, vector<long>& MPIPos){
492         try {
493                                 
494                 MPI_Status status; 
495                 int pid;
496                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
497                 
498                 for(int i=0;i<num;i++){
499                         
500                         if (m->control_pressed) {       return 1;       }
501                         
502                         //read next sequence
503                         int length = MPIPos[start+i+1] - MPIPos[start+i];
504         
505                         char* buf4 = new char[length];
506                         MPI_File_read_at(inMPI, MPIPos[start+i], buf4, length, MPI_CHAR, &status);
507                         
508                         string tempBuf = buf4;
509                         if (tempBuf.length() > length) { tempBuf = tempBuf.substr(0, length);  }
510                         istringstream iss (tempBuf,istringstream::in);
511                         delete buf4;
512
513                         Sequence* candidateSeq = new Sequence(iss);  gobble(iss);
514                                 
515                         if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
516                                 
517                                 if      (candidateSeq->getAligned().length() != templateSeqsLength) {  //chimeracheck does not require seqs to be aligned
518                                         m->mothurOut(candidateSeq->getName() + " is not the same length as the template sequences. Skipping."); m->mothurOutEndLine();
519                                 }else{
520                                         //find chimeras
521                                         chimera->getChimeras(candidateSeq);
522                                         
523                                         if (m->control_pressed) {       delete candidateSeq; return 1;  }
524                 
525                                         //print results
526                                         bool isChimeric = chimera->print(outMPI, outAccMPI);
527                                         if (isChimeric) { MPIWroteAccnos = true;  }
528                                 }
529                         }
530                         delete candidateSeq;
531                         
532                         //report progress
533                         if((i+1) % 100 == 0){  cout << "Processing sequence: " << (i+1) << endl;        m->mothurOutJustToLog("Processing sequence: " + toString(i+1) + "\n");          }
534                 }
535                 //report progress
536                 if(num % 100 != 0){             cout << "Processing sequence: " << num << endl; m->mothurOutJustToLog("Processing sequence: " + toString(num) + "\n");  }
537                 
538                                 
539                 return 0;
540         }
541         catch(exception& e) {
542                 m->errorOut(e, "ChimeraPintailCommand", "driverMPI");
543                 exit(1);
544         }
545 }
546 #endif
547
548 /**************************************************************************************************/
549
550 int ChimeraPintailCommand::createProcesses(string outputFileName, string filename, string accnos) {
551         try {
552 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
553                 int process = 0;
554                 //              processIDS.resize(0);
555                 
556                 //loop through and create all the processes you want
557                 while (process != processors) {
558                         int pid = fork();
559                         
560                         if (pid > 0) {
561                                 processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
562                                 process++;
563                         }else if (pid == 0){
564                                 driver(lines[process], outputFileName + toString(getpid()) + ".temp", filename, accnos + toString(getpid()) + ".temp");
565                                 exit(0);
566                         }else { m->mothurOut("unable to spawn the necessary processes."); m->mothurOutEndLine(); exit(0); }
567                 }
568                 
569                 //force parent to wait until all the processes are done
570                 for (int i=0;i<processors;i++) { 
571                         int temp = processIDS[i];
572                         wait(&temp);
573                 }
574                 
575                 return 0;
576 #endif          
577         }
578         catch(exception& e) {
579                 m->errorOut(e, "ChimeraPintailCommand", "createProcesses");
580                 exit(1);
581         }
582 }
583
584 /**************************************************************************************************/
585
586