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