]> git.donarmstrong.com Git - mothur.git/blob - chimerapintailcommand.cpp
added cluster.split command
[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                                 for(int i = 1; i < processors; i++) { 
253                                         MPI_Send(&numSeqs, 1, MPI_INT, i, tag, MPI_COMM_WORLD);
254                                         MPI_Send(&MPIPos[0], (numSeqs+1), MPI_LONG, i, tag, MPI_COMM_WORLD);
255                                 }
256                                 
257                                 //figure out how many sequences you have to align
258                                 numSeqsPerProcessor = numSeqs / processors;
259                                 int startIndex =  pid * numSeqsPerProcessor;
260                                 if(pid == (processors - 1)){    numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor;      }
261                                 
262                         
263                                 //align your part
264                                 driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, outMPIAccnos, MPIPos);
265                                 
266                                 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;  }
267                                 
268                                 for (int i = 1; i < processors; i++) {
269                                         bool tempResult;
270                                         MPI_Recv(&tempResult, 1, MPI_INT, i, tag, MPI_COMM_WORLD, &status);
271                                         if (tempResult != 0) { MPIWroteAccnos = true; }
272                                 }
273                         }else{ //you are a child process
274                                 MPI_Recv(&numSeqs, 1, MPI_INT, 0, tag, MPI_COMM_WORLD, &status);
275                                 MPIPos.resize(numSeqs+1);
276                                 MPI_Recv(&MPIPos[0], (numSeqs+1), MPI_LONG, 0, tag, MPI_COMM_WORLD, &status);
277                                 
278                                 //figure out how many sequences you have to align
279                                 numSeqsPerProcessor = numSeqs / processors;
280                                 int startIndex =  pid * numSeqsPerProcessor;
281                                 if(pid == (processors - 1)){    numSeqsPerProcessor = numSeqs - pid * numSeqsPerProcessor;      }
282                                 
283                                 
284                                 //align your part
285                                 driverMPI(startIndex, numSeqsPerProcessor, inMPI, outMPI, outMPIAccnos, MPIPos);
286                                 
287                                 if (m->control_pressed) {  MPI_File_close(&inMPI);  MPI_File_close(&outMPI);   MPI_File_close(&outMPIAccnos);  delete chimera; return 0;  }
288
289                                 MPI_Send(&MPIWroteAccnos, 1, MPI_INT, 0, tag, MPI_COMM_WORLD); 
290                         }
291                         
292                         //close files 
293                         MPI_File_close(&inMPI);
294                         MPI_File_close(&outMPI);
295                         MPI_File_close(&outMPIAccnos);
296                         MPI_Barrier(MPI_COMM_WORLD); //make everyone wait - just in case
297                         
298                         //delete accnos file if blank
299                         if (pid == 0) {
300                                 if (!MPIWroteAccnos) { 
301                                         //MPI_Info info;
302                                         //MPI_File_delete(outAccnosFilename, info);
303                                         hasAccnos = false;      
304                                         remove(accnosFileName.c_str()); 
305                                 }
306                         }
307
308         #else
309         
310                 //break up file
311                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
312                         if(processors == 1){
313                                 ifstream inFASTA;
314                                 openInputFile(fastafile, inFASTA);
315                                 numSeqs=count(istreambuf_iterator<char>(inFASTA),istreambuf_iterator<char>(), '>');
316                                 inFASTA.close();
317                                 
318                                 lines.push_back(new linePair(0, numSeqs));
319                                 
320                                 driver(lines[0], outputFileName, fastafile, accnosFileName);
321                                 
322                                 if (m->control_pressed) { 
323                                         remove(outputFileName.c_str()); 
324                                         remove(accnosFileName.c_str());
325                                         for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
326                                         delete chimera;
327                                         return 0;
328                                 }
329                                 
330                                 //delete accnos file if its blank 
331                                 if (isBlank(accnosFileName)) {  remove(accnosFileName.c_str());  hasAccnos = false; }
332                                                                 
333                         }else{
334                                 vector<int> positions;
335                                 processIDS.resize(0);
336                                 
337                                 ifstream inFASTA;
338                                 openInputFile(fastafile, inFASTA);
339                                 
340                                 string input;
341                                 while(!inFASTA.eof()){
342                                         input = getline(inFASTA);
343                                         if (input.length() != 0) {
344                                                 if(input[0] == '>'){    long int pos = inFASTA.tellg(); positions.push_back(pos - input.length() - 1);  }
345                                         }
346                                 }
347                                 inFASTA.close();
348                                 
349                                 numSeqs = positions.size();
350                                 
351                                 int numSeqsPerProcessor = numSeqs / processors;
352                                 
353                                 for (int i = 0; i < processors; i++) {
354                                         long int startPos = positions[ i * numSeqsPerProcessor ];
355                                         if(i == processors - 1){
356                                                 numSeqsPerProcessor = numSeqs - i * numSeqsPerProcessor;
357                                         }
358                                         lines.push_back(new linePair(startPos, numSeqsPerProcessor));
359                                 }
360                                 
361                                 
362                                 createProcesses(outputFileName, fastafile, accnosFileName); 
363                         
364                                 rename((outputFileName + toString(processIDS[0]) + ".temp").c_str(), outputFileName.c_str());
365                                         
366                                 //append output files
367                                 for(int i=1;i<processors;i++){
368                                         appendFiles((outputFileName + toString(processIDS[i]) + ".temp"), outputFileName);
369                                         remove((outputFileName + toString(processIDS[i]) + ".temp").c_str());
370                                 }
371                                 
372                                 vector<string> nonBlankAccnosFiles;
373                                 //delete blank accnos files generated with multiple processes
374                                 for(int i=0;i<processors;i++){  
375                                         if (!(isBlank(accnosFileName + toString(processIDS[i]) + ".temp"))) {
376                                                 nonBlankAccnosFiles.push_back(accnosFileName + toString(processIDS[i]) + ".temp");
377                                         }else { remove((accnosFileName + toString(processIDS[i]) + ".temp").c_str());  }
378                                 }
379                                 
380                                 //append accnos files
381                                 if (nonBlankAccnosFiles.size() != 0) { 
382                                         rename(nonBlankAccnosFiles[0].c_str(), accnosFileName.c_str());
383                                         
384                                         for (int h=1; h < nonBlankAccnosFiles.size(); h++) {
385                                                 appendFiles(nonBlankAccnosFiles[h], accnosFileName);
386                                                 remove(nonBlankAccnosFiles[h].c_str());
387                                         }
388                                 }else{ hasAccnos = false;  }
389                                 
390                                 if (m->control_pressed) { 
391                                         remove(outputFileName.c_str()); 
392                                         remove(accnosFileName.c_str());
393                                         for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
394                                         delete chimera;
395                                         return 0;
396                                 }
397                         }
398
399                 #else
400                         ifstream inFASTA;
401                         openInputFile(fastafile, inFASTA);
402                         numSeqs=count(istreambuf_iterator<char>(inFASTA),istreambuf_iterator<char>(), '>');
403                         inFASTA.close();
404                         lines.push_back(new linePair(0, numSeqs));
405                         
406                         driver(lines[0], outputFileName, fastafile, accnosFileName);
407                         
408                         if (m->control_pressed) { 
409                                         remove(outputFileName.c_str()); 
410                                         remove(accnosFileName.c_str());
411                                         for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
412                                         delete chimera;
413                                         return 0;
414                         }
415                         
416                         //delete accnos file if its blank 
417                         if (isBlank(accnosFileName)) {  remove(accnosFileName.c_str());  hasAccnos = false; }
418                 #endif
419                 
420         #endif  
421         
422                 delete chimera;
423                 for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
424                 
425                 m->mothurOutEndLine();
426                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
427                 m->mothurOut(outputFileName); m->mothurOutEndLine();    
428                 if (hasAccnos) {  m->mothurOut(accnosFileName); m->mothurOutEndLine();  }
429                 m->mothurOutEndLine();
430                 m->mothurOutEndLine(); m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(numSeqs) + " sequences."); m->mothurOutEndLine();
431                 
432                 return 0;
433                 
434         }
435         catch(exception& e) {
436                 m->errorOut(e, "ChimeraPintailCommand", "execute");
437                 exit(1);
438         }
439 }
440 //**********************************************************************************************************************
441
442 int ChimeraPintailCommand::driver(linePair* line, string outputFName, string filename, string accnos){
443         try {
444                 ofstream out;
445                 openOutputFile(outputFName, out);
446                 
447                 ofstream out2;
448                 openOutputFile(accnos, out2);
449                 
450                 ifstream inFASTA;
451                 openInputFile(filename, inFASTA);
452
453                 inFASTA.seekg(line->start);
454                 
455                 for(int i=0;i<line->numSeqs;i++){
456                 
457                         if (m->control_pressed) {       return 1;       }
458                 
459                         Sequence* candidateSeq = new Sequence(inFASTA);  gobble(inFASTA);
460                                 
461                         if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
462                                 
463                                 if (candidateSeq->getAligned().length() != templateSeqsLength)  {  //chimeracheck does not require seqs to be aligned
464                                         m->mothurOut(candidateSeq->getName() + " is not the same length as the template sequences. Skipping."); m->mothurOutEndLine();
465                                 }else{
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                         }
475                         delete candidateSeq;
476                         
477                         //report progress
478                         if((i+1) % 100 == 0){   m->mothurOut("Processing sequence: " + toString(i+1)); m->mothurOutEndLine();           }
479                 }
480                 //report progress
481                 if((line->numSeqs) % 100 != 0){ m->mothurOut("Processing sequence: " + toString(line->numSeqs)); m->mothurOutEndLine();         }
482                 
483                 out.close();
484                 out2.close();
485                 inFASTA.close();
486                                 
487                 return 0;
488         }
489         catch(exception& e) {
490                 m->errorOut(e, "ChimeraPintailCommand", "driver");
491                 exit(1);
492         }
493 }
494 //**********************************************************************************************************************
495 #ifdef USE_MPI
496 int ChimeraPintailCommand::driverMPI(int start, int num, MPI_File& inMPI, MPI_File& outMPI, MPI_File& outAccMPI, vector<long>& MPIPos){
497         try {
498                                 
499                 MPI_Status status; 
500                 int pid;
501                 MPI_Comm_rank(MPI_COMM_WORLD, &pid); //find out who we are
502                 
503                 for(int i=0;i<num;i++){
504                         
505                         if (m->control_pressed) {       return 1;       }
506                         
507                         //read next sequence
508                         int length = MPIPos[start+i+1] - MPIPos[start+i];
509         
510                         char* buf4 = new char[length];
511                         MPI_File_read_at(inMPI, MPIPos[start+i], buf4, length, MPI_CHAR, &status);
512                         
513                         string tempBuf = buf4;
514                         if (tempBuf.length() > length) { tempBuf = tempBuf.substr(0, length);  }
515                         istringstream iss (tempBuf,istringstream::in);
516                         delete buf4;
517
518                         Sequence* candidateSeq = new Sequence(iss);  gobble(iss);
519                                 
520                         if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
521                                 
522                                 if      (candidateSeq->getAligned().length() != templateSeqsLength) {  //chimeracheck does not require seqs to be aligned
523                                         m->mothurOut(candidateSeq->getName() + " is not the same length as the template sequences. Skipping."); m->mothurOutEndLine();
524                                 }else{
525                                         //find chimeras
526                                         chimera->getChimeras(candidateSeq);
527                                         
528                                         if (m->control_pressed) {       delete candidateSeq; return 1;  }
529                 
530                                         //print results
531                                         bool isChimeric = chimera->print(outMPI, outAccMPI);
532                                         if (isChimeric) { MPIWroteAccnos = true;  }
533                                 }
534                         }
535                         delete candidateSeq;
536                         
537                         //report progress
538                         if((i+1) % 100 == 0){  cout << "Processing sequence: " << (i+1) << endl;        m->mothurOutJustToLog("Processing sequence: " + toString(i+1) + "\n");          }
539                 }
540                 //report progress
541                 if(num % 100 != 0){             cout << "Processing sequence: " << num << endl; m->mothurOutJustToLog("Processing sequence: " + toString(num) + "\n");  }
542                 
543                                 
544                 return 0;
545         }
546         catch(exception& e) {
547                 m->errorOut(e, "ChimeraPintailCommand", "driverMPI");
548                 exit(1);
549         }
550 }
551 #endif
552
553 /**************************************************************************************************/
554
555 int ChimeraPintailCommand::createProcesses(string outputFileName, string filename, string accnos) {
556         try {
557 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
558                 int process = 0;
559                 //              processIDS.resize(0);
560                 
561                 //loop through and create all the processes you want
562                 while (process != processors) {
563                         int pid = fork();
564                         
565                         if (pid > 0) {
566                                 processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
567                                 process++;
568                         }else if (pid == 0){
569                                 driver(lines[process], outputFileName + toString(getpid()) + ".temp", filename, accnos + toString(getpid()) + ".temp");
570                                 exit(0);
571                         }else { m->mothurOut("unable to spawn the necessary processes."); m->mothurOutEndLine(); exit(0); }
572                 }
573                 
574                 //force parent to wait until all the processes are done
575                 for (int i=0;i<processors;i++) { 
576                         int temp = processIDS[i];
577                         wait(&temp);
578                 }
579                 
580                 return 0;
581 #endif          
582         }
583         catch(exception& e) {
584                 m->errorOut(e, "ChimeraPintailCommand", "createProcesses");
585                 exit(1);
586         }
587 }
588
589 /**************************************************************************************************/
590
591