]> git.donarmstrong.com Git - mothur.git/blob - chimeraseqscommand.cpp
65e082b93a6a97e162af3aca3aa576915f22bd18
[mothur.git] / chimeraseqscommand.cpp
1 /*
2  *  chimeraseqscommand.cpp
3  *  Mothur
4  *
5  *  Created by Sarah Westcott on 6/29/09.
6  *  Copyright 2009 Schloss Lab UMASS Amherst. All rights reserved.
7  *
8  */
9
10 #include "chimeraseqscommand.h"
11 #include "bellerophon.h"
12 #include "pintail.h"
13 #include "ccode.h"
14 #include "chimeracheckrdp.h"
15 #include "chimeraslayer.h"
16
17
18 //***************************************************************************************************************
19
20 ChimeraSeqsCommand::ChimeraSeqsCommand(string option)  {
21         try {
22                 abort = false;
23                 
24                 //allow user to run help
25                 if(option == "help") { help(); abort = true; }
26                 
27                 else {
28                         //valid paramters for this command
29                         string Array[] =  {"fasta", "filter", "correction", "processors", "method", "window", "increment", "template", "conservation", "quantile", "mask", 
30                         "numwanted", "ksize", "svg", "name", "match","mismatch", "divergence", "minsim","mincov","minbs", "minsnp","parents", "iters","outputdir","inputdir", "search","realign" };
31                         vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));
32                         
33                         OptionParser parser(option);
34                         map<string,string> parameters = parser.getParameters();
35                         
36                         ValidParameters validParameter;
37                         map<string,string>::iterator it;
38                         
39                         //check to make sure all parameters are valid for command
40                         for (it = parameters.begin(); it != parameters.end(); it++) { 
41                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }
42                         }
43                         
44                         //if the user changes the input directory command factory will send this info to us in the output parameter 
45                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              
46                         if (inputDir == "not found"){   inputDir = "";          }
47                         else {
48                                 string path;
49                                 it = parameters.find("fasta");
50                                 //user has given a template file
51                                 if(it != parameters.end()){ 
52                                         path = hasPath(it->second);
53                                         //if the user has not given a path then, add inputdir. else leave path alone.
54                                         if (path == "") {       parameters["fasta"] = inputDir + it->second;            }
55                                 }
56                                 
57                                 it = parameters.find("template");
58                                 //user has given a template file
59                                 if(it != parameters.end()){ 
60                                         path = hasPath(it->second);
61                                         //if the user has not given a path then, add inputdir. else leave path alone.
62                                         if (path == "") {       parameters["template"] = inputDir + it->second;         }
63                                 }
64                                 
65                                 it = parameters.find("conservation");
66                                 //user has given a template file
67                                 if(it != parameters.end()){ 
68                                         path = hasPath(it->second);
69                                         //if the user has not given a path then, add inputdir. else leave path alone.
70                                         if (path == "") {       parameters["conservation"] = inputDir + it->second;             }
71                                 }
72                                 
73                                 it = parameters.find("quantile");
74                                 //user has given a template file
75                                 if(it != parameters.end()){ 
76                                         path = hasPath(it->second);
77                                         //if the user has not given a path then, add inputdir. else leave path alone.
78                                         if (path == "") {       parameters["quantile"] = inputDir + it->second;         }
79                                 }
80                                 
81                                 it = parameters.find("name");
82                                 //user has given a template file
83                                 if(it != parameters.end()){ 
84                                         path = hasPath(it->second);
85                                         //if the user has not given a path then, add inputdir. else leave path alone.
86                                         if (path == "") {       parameters["name"] = inputDir + it->second;             }
87                                 }
88                         }
89
90                         
91                         //check for required parameters
92                         fastafile = validParameter.validFile(parameters, "fasta", true);
93                         if (fastafile == "not open") { abort = true; }
94                         else if (fastafile == "not found") { fastafile = ""; m->mothurOut("fasta is a required parameter for the chimera.seqs command."); m->mothurOutEndLine(); abort = true;  }       
95                         
96                         //if the user changes the output directory command factory will send this info to us in the output parameter 
97                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  
98                                 outputDir = ""; 
99                                 outputDir += hasPath(fastafile); //if user entered a file with a path then preserve it  
100                         }
101
102                         templatefile = validParameter.validFile(parameters, "template", true);
103                         if (templatefile == "not open") { abort = true; }
104                         else if (templatefile == "not found") { templatefile = "";  }   
105                         
106                         consfile = validParameter.validFile(parameters, "conservation", true);
107                         if (consfile == "not open") { abort = true; }
108                         else if (consfile == "not found") { consfile = "";  }   
109                         
110                         quanfile = validParameter.validFile(parameters, "quantile", true);
111                         if (quanfile == "not open") { abort = true; }
112                         else if (quanfile == "not found") { quanfile = "";  }
113                         
114                         namefile = validParameter.validFile(parameters, "name", true);
115                         if (namefile == "not open") { abort = true; }
116                         else if (namefile == "not found") { namefile = "";  }
117
118                         maskfile = validParameter.validFile(parameters, "mask", false);
119                         if (maskfile == "not found") { maskfile = "";  }        
120                         else if (maskfile != "default")  { 
121                                 if (inputDir != "") {
122                                         string path = hasPath(maskfile);
123                                         //if the user has not given a path then, add inputdir. else leave path alone.
124                                         if (path == "") {       maskfile = inputDir + maskfile;         }
125                                 }
126
127                                 ifstream in;
128                                 int     ableToOpen = openInputFile(maskfile, in);
129                                 if (ableToOpen == 1) { abort = true; }
130                                 in.close();
131                         }
132                         
133                         method = validParameter.validFile(parameters, "method", false);                 if (method == "not found") { method = "pintail"; }
134                         
135                         string temp;
136                         temp = validParameter.validFile(parameters, "filter", false);                   if (temp == "not found") { temp = "F"; }
137                         filter = isTrue(temp);
138                         
139                         temp = validParameter.validFile(parameters, "correction", false);               if (temp == "not found") { temp = "T"; }
140                         correction = isTrue(temp);
141                         
142                         temp = validParameter.validFile(parameters, "processors", false);               if (temp == "not found") { temp = "1"; }
143                         convert(temp, processors);
144                         
145                         temp = validParameter.validFile(parameters, "ksize", false);                    if (temp == "not found") { temp = "7"; }
146                         convert(temp, ksize);
147                         
148                         temp = validParameter.validFile(parameters, "svg", false);                              if (temp == "not found") { temp = "F"; }
149                         svg = isTrue(temp);
150                         
151                         temp = validParameter.validFile(parameters, "window", false);   
152                         if ((temp == "not found") && (method == "chimeraslayer")) { temp = "50"; }                      
153                         else if (temp == "not found") { temp = "0"; }
154                         convert(temp, window);
155                         
156                         temp = validParameter.validFile(parameters, "match", false);                    if (temp == "not found") { temp = "5"; }
157                         convert(temp, match);
158                         
159                         temp = validParameter.validFile(parameters, "mismatch", false);                 if (temp == "not found") { temp = "-4"; }
160                         convert(temp, mismatch);
161                         
162                         temp = validParameter.validFile(parameters, "divergence", false);               if (temp == "not found") { temp = "1.007"; }
163                         convert(temp, divR);
164                         
165                         temp = validParameter.validFile(parameters, "minsim", false);                   if (temp == "not found") { temp = "90"; }
166                         convert(temp, minSimilarity);
167                         
168                         temp = validParameter.validFile(parameters, "mincov", false);                   if (temp == "not found") { temp = "70"; }
169                         convert(temp, minCoverage);
170                         
171                         temp = validParameter.validFile(parameters, "minbs", false);                    if (temp == "not found") { temp = "90"; }
172                         convert(temp, minBS);
173                         
174                         temp = validParameter.validFile(parameters, "minsnp", false);                   if (temp == "not found") { temp = "10"; }
175                         convert(temp, minSNP);
176
177                         temp = validParameter.validFile(parameters, "parents", false);                  if (temp == "not found") { temp = "3"; }
178                         convert(temp, parents); 
179                         
180                         temp = validParameter.validFile(parameters, "realign", false);                  if (temp == "not found") { temp = "f"; }
181                         realign = isTrue(temp); 
182                         
183                         search = validParameter.validFile(parameters, "search", false);                 if (search == "not found") { search = "distance"; }
184                         
185                         temp = validParameter.validFile(parameters, "iters", false);    
186                         if ((temp == "not found") && (method == "chimeraslayer")) { temp = "100"; }             
187                         else if (temp == "not found") { temp = "1000"; }
188                         convert(temp, iters); 
189                          
190                         temp = validParameter.validFile(parameters, "increment", false);                
191                         if ((temp == "not found") && (method == "chimeracheck")) { temp = "10"; }
192                         else if ((temp == "not found") && (method == "chimeraslayer")) { temp = "5"; }
193                         else if (temp == "not found") { temp = "25"; }
194                         convert(temp, increment);
195                         
196                         temp = validParameter.validFile(parameters, "numwanted", false);
197                         if ((temp == "not found") && (method == "chimeraslayer")) { temp = "15"; }              
198                         else if (temp == "not found") { temp = "20"; }
199                         convert(temp, numwanted);
200
201                         if ((search != "distance") && (search != "blast") && (search != "kmer")) { m->mothurOut(search + " is not a valid search."); m->mothurOutEndLine(); abort = true;  }
202                         
203                         if (((method != "bellerophon")) && (templatefile == "")) { m->mothurOut("You must provide a template file with the pintail, ccode, chimeraslayer or chimeracheck methods."); m->mothurOutEndLine(); abort = true;  }
204                         
205
206                 }
207         }
208         catch(exception& e) {
209                 m->errorOut(e, "ChimeraSeqsCommand", "ChimeraSeqsCommand");
210                 exit(1);
211         }
212 }
213 //**********************************************************************************************************************
214
215 void ChimeraSeqsCommand::help(){
216         try {
217         
218                 //"fasta", "filter", "correction", "processors", "method", "window", "increment", "template", "conservation", "quantile", "mask", "numwanted", "ksize", "svg", "name"
219                 //m->mothurOut("chimera.seqs ASSUMES that your sequences are ALIGNED and if using a template that the template file sequences are the same length as the fasta file sequences.\n\n");
220                 m->mothurOut("The chimera.seqs command reads a fastafile and creates list of potentially chimeric sequences.\n");
221                 m->mothurOut("The chimera.seqs command parameters are fasta, filter, correction, processors, mask, method, window, increment, template, conservation, quantile, numwanted, ksize, svg, name, iters, search, realign.\n");
222                 m->mothurOut("The fasta parameter is always required and template is required if using pintail, ccode or chimeracheck.\n");
223                 m->mothurOut("The filter parameter allows you to specify if you would like to apply a vertical and 50% soft filter. \n");
224                 m->mothurOut("The correction parameter allows you to put more emphasis on the distance between highly similar sequences and less emphasis on the differences between remote homologs.\n");
225                 m->mothurOut("The processors parameter allows you to specify how many processors you would like to use.  The default is 1. \n");
226                 m->mothurOut("The method parameter allows you to specify the method for finding chimeric sequences.  The default is pintail. Options include bellerophon, ccode and chimeracheck \n");
227                 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. \n");
228                 m->mothurOut("The window parameter allows you to specify the window size for searching for chimeras. \n");
229                 m->mothurOut("The increment parameter allows you to specify how far you move each window while finding chimeric sequences.\n");
230                 m->mothurOut("The template parameter allows you to enter a template file containing known non-chimeric sequences. \n");
231                 m->mothurOut("The conservation parameter allows you to enter a frequency file containing the highest bases frequency at each place in the alignment.\n");
232                 m->mothurOut("The quantile parameter allows you to enter a file containing quantiles for a template files sequences.\n");
233                 m->mothurOut("The numwanted parameter allows you to specify how many sequences you would each query sequence compared with.\n");
234                 m->mothurOut("The ksize parameter allows you to input kmersize. \n");
235                 m->mothurOut("The svg parameter allows you to specify whether or not you would like a svg file outputted for each query sequence.\n");
236                 m->mothurOut("The name parameter allows you to enter a file containing names of sequences you would like .svg files for.\n");
237                 m->mothurOut("The iters parameter allows you to specify the number of bootstrap iters to do with the chimeraslayer method.\n");
238                 m->mothurOut("The minsim parameter allows you .... \n");
239                 m->mothurOut("The mincov parameter allows you to specify minimum coverage by closest matches found in template. Default is 70, meaning 70%. \n");
240                 m->mothurOut("The minbs parameter allows you to specify minimum bootstrap support for calling a sequence chimeric. Default is 90, meaning 90%. \n");
241                 m->mothurOut("The minsnp parameter allows you to specify percent of SNPs to sample on each side of breakpoint for computing bootstrap support (default: 10) \n");
242                 m->mothurOut("The search parameter allows you to specify search method for finding the closest parent. Choices are distance, blast, and kmer, default distance.  -used only by chimeraslayer. \n");
243                 m->mothurOut("The realign parameter allows you to realign the query to the potential paretns. Choices are true or false, default false.  -used only by chimeraslayer. \n");
244                 m->mothurOut("NOT ALL PARAMETERS ARE USED BY ALL METHODS. Please look below for method specifics.\n\n");
245                 m->mothurOut("Details for each method: \n"); 
246                 m->mothurOut("\tpintail: \n"); 
247                 m->mothurOut("\t\tparameters: fasta=required, template=required, filter=F, mask=no mask, processors=1, window=300, increment=25, conservation=not required, but will improve speed, quantile=not required, but will greatly improve speed. \n"); 
248                 m->mothurOut("\t\tIf you have run chimera.seqs using pintail a .quan and .freq file will be created for your template, if you have not provided them for use in future command executions.\n");
249                 m->mothurOut("\tbellerophon: \n"); 
250                 m->mothurOut("\t\tparameters: fasta=required, filter=F, processors=1, window=1/4 length of seq, increment=25, correction=T. \n"); 
251                 m->mothurOut("\tccode: \n"); 
252                 m->mothurOut("\t\tparameters: fasta=required, template=required, filter=F, mask=no mask, processors=1, window=10% of length, numwanted=20\n"); 
253                 m->mothurOut("\tchimeracheck: \n"); 
254                 m->mothurOut("\t\tparameters: fasta=required, template=required, processors=1, increment=10, ksize=7, svg=F, name=none\n\n"); 
255                 m->mothurOut("\tchimeraslayer: \n"); 
256                 m->mothurOut("\t\tparameters: fasta=required, template=required, processors=1, increment=10, mask=no mask, numwanted=10, match=5, mismatch=-4, divergence=1.0, minsim=90, parents=5, iters=1000, window=100. \n\n"); 
257                 m->mothurOut("The chimera.seqs command should be in the following format: \n");
258                 m->mothurOut("chimera.seqs(fasta=yourFastaFile, filter=yourFilter, correction=yourCorrection, processors=yourProcessors, method=bellerophon) \n");
259                 m->mothurOut("Example: chimera.seqs(fasta=AD.align, filter=True, correction=true, method=bellerophon, window=200) \n");
260                 m->mothurOut("Note: No spaces between parameter labels (i.e. fasta), '=' and parameters (i.e.yourFastaFile).\n\n");     
261         }
262         catch(exception& e) {
263                 m->errorOut(e, "ChimeraSeqsCommand", "help");
264                 exit(1);
265         }
266 }
267
268 //***************************************************************************************************************
269
270 ChimeraSeqsCommand::~ChimeraSeqsCommand(){      /*      do nothing      */      }
271
272 //***************************************************************************************************************
273
274 int ChimeraSeqsCommand::execute(){
275         try{
276                 
277                 if (abort == true) { return 0; }
278                 
279                 int start = time(NULL); 
280                 
281                 if (method == "bellerophon")                    {               chimera = new Bellerophon(fastafile, outputDir);                        }
282                 else if (method == "pintail")                   {               chimera = new Pintail(fastafile, outputDir);                            }
283                 else if (method == "ccode")                             {               chimera = new Ccode(fastafile, outputDir);                                      }
284                 else if (method == "chimeracheck")              {               chimera = new ChimeraCheckRDP(fastafile, outputDir);            }
285                 else if (method == "chimeraslayer")             {               chimera = new ChimeraSlayer(search, realign, fastafile);        }
286                 else { m->mothurOut("Not a valid method."); m->mothurOutEndLine(); return 0;            }
287                 
288                 //set user options
289                 if (maskfile == "default") { m->mothurOut("I am using the default 236627 EU009184.1 Shigella dysenteriae str. FBD013."); m->mothurOutEndLine();  }
290                 
291                 chimera->setCons(consfile);     
292                 chimera->setQuantiles(quanfile);                                
293                 chimera->setMask(maskfile);
294                 chimera->setFilter(filter);
295                 chimera->setCorrection(correction);
296                 chimera->setProcessors(processors);
297                 chimera->setWindow(window);
298                 chimera->setIncrement(increment);
299                 chimera->setNumWanted(numwanted);
300                 chimera->setKmerSize(ksize);
301                 chimera->setSVG(svg);
302                 chimera->setName(namefile);
303                 chimera->setMatch(match);
304                 chimera->setMisMatch(mismatch);
305                 chimera->setDivR(divR);
306                 chimera->setParents(parents);
307                 chimera->setMinSim(minSimilarity);
308                 chimera->setMinCoverage(minCoverage);
309                 chimera->setMinBS(minBS);
310                 chimera->setMinSNP(minSNP);
311                 chimera->setIters(iters);
312                 
313
314                 string outputFileName = outputDir + getRootName(getSimpleName(fastafile)) + method + maskfile + ".chimeras";
315                 string accnosFileName = outputDir + getRootName(getSimpleName(fastafile)) + method + maskfile + ".accnos";
316                 bool hasAccnos = true;
317                 
318                 if (method == "bellerophon") {//run bellerophon separately since you need to read entire fastafile to run it
319                         chimera->getChimeras();
320                         
321                         if (m->control_pressed) { delete chimera;       return 0;       }
322                         
323                         ofstream out;
324                         openOutputFile(outputFileName, out);
325                         
326                         ofstream out2;
327                         openOutputFile(accnosFileName, out2);
328                         
329                         chimera->print(out, out2);
330                         out.close();
331                         out2.close(); 
332                         
333                         if (m->control_pressed) { remove(accnosFileName.c_str()); remove(outputFileName.c_str()); delete chimera;       return 0;       }
334                         
335                         //delete accnos file if its blank 
336                         if (isBlank(accnosFileName)) {  remove(accnosFileName.c_str());  hasAccnos = false; }
337                         
338                         m->mothurOutEndLine();
339                         m->mothurOut("Output File Names: "); m->mothurOutEndLine();
340                         m->mothurOut(outputFileName); m->mothurOutEndLine();    
341                         if (hasAccnos) {  m->mothurOut(accnosFileName); m->mothurOutEndLine();  }
342                         m->mothurOutEndLine();
343                         
344                         delete chimera;
345                         return 0;
346                 }
347                 
348                 //reads template
349                 chimera->setTemplateFile(templatefile);
350                 
351                 if (m->control_pressed) { delete chimera;       return 0;       }
352                 
353                 if  (method != "chimeracheck") {   
354                         if (chimera->getUnaligned()) { 
355                                 m->mothurOut("Your template sequences are different lengths, please correct."); m->mothurOutEndLine(); 
356                                 delete chimera;
357                                 return 0; 
358                         }
359                 }
360                 
361                 //some methods need to do prep work before processing the chimeras
362                 chimera->doPrep(); 
363                 
364                 if (m->control_pressed) { delete chimera;       return 0;       }
365                 
366                 templateSeqsLength = chimera->getLength();
367                 
368                 ofstream outHeader;
369                 string tempHeader = outputDir + getRootName(getSimpleName(fastafile)) + method + maskfile + ".chimeras.tempHeader";
370                 openOutputFile(tempHeader, outHeader);
371                 
372                 chimera->printHeader(outHeader);
373                 outHeader.close();
374                 
375                 
376                 //break up file
377                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
378                         if(processors == 1){
379                                 ifstream inFASTA;
380                                 openInputFile(fastafile, inFASTA);
381                                 numSeqs=count(istreambuf_iterator<char>(inFASTA),istreambuf_iterator<char>(), '>');
382                                 inFASTA.close();
383                                 
384                                 lines.push_back(new linePair(0, numSeqs));
385                                 
386                                 driver(lines[0], outputFileName, fastafile, accnosFileName);
387                                 
388                                 if (m->control_pressed) { 
389                                         remove(outputFileName.c_str()); 
390                                         remove(tempHeader.c_str()); 
391                                         remove(accnosFileName.c_str());
392                                         for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
393                                         delete chimera;
394                                         return 0;
395                                 }
396                                 
397                                 //delete accnos file if its blank 
398                                 if (isBlank(accnosFileName)) {  remove(accnosFileName.c_str());  hasAccnos = false; }
399                                                                 
400                         }else{
401                                 vector<int> positions;
402                                 processIDS.resize(0);
403                                 
404                                 ifstream inFASTA;
405                                 openInputFile(fastafile, inFASTA);
406                                 
407                                 string input;
408                                 while(!inFASTA.eof()){
409                                         input = getline(inFASTA);
410                                         if (input.length() != 0) {
411                                                 if(input[0] == '>'){    long int pos = inFASTA.tellg(); positions.push_back(pos - input.length() - 1);  }
412                                         }
413                                 }
414                                 inFASTA.close();
415                                 
416                                 numSeqs = positions.size();
417                                 
418                                 int numSeqsPerProcessor = numSeqs / processors;
419                                 
420                                 for (int i = 0; i < processors; i++) {
421                                         long int startPos = positions[ i * numSeqsPerProcessor ];
422                                         if(i == processors - 1){
423                                                 numSeqsPerProcessor = numSeqs - i * numSeqsPerProcessor;
424                                         }
425                                         lines.push_back(new linePair(startPos, numSeqsPerProcessor));
426                                 }
427                                 
428                                 
429                                 createProcesses(outputFileName, fastafile, accnosFileName); 
430                         
431                                 rename((outputFileName + toString(processIDS[0]) + ".temp").c_str(), outputFileName.c_str());
432                                         
433                                 //append output files
434                                 for(int i=1;i<processors;i++){
435                                         appendOutputFiles((outputFileName + toString(processIDS[i]) + ".temp"), outputFileName);
436                                         remove((outputFileName + toString(processIDS[i]) + ".temp").c_str());
437                                 }
438                                 
439                                 vector<string> nonBlankAccnosFiles;
440                                 //delete blank accnos files generated with multiple processes
441                                 for(int i=0;i<processors;i++){  
442                                         if (!(isBlank(accnosFileName + toString(processIDS[i]) + ".temp"))) {
443                                                 nonBlankAccnosFiles.push_back(accnosFileName + toString(processIDS[i]) + ".temp");
444                                         }else { remove((accnosFileName + toString(processIDS[i]) + ".temp").c_str());  }
445                                 }
446                                 
447                                 //append accnos files
448                                 if (nonBlankAccnosFiles.size() != 0) { 
449                                         rename(nonBlankAccnosFiles[0].c_str(), accnosFileName.c_str());
450                                         
451                                         for (int h=1; h < nonBlankAccnosFiles.size(); h++) {
452                                                 appendOutputFiles(nonBlankAccnosFiles[h], accnosFileName);
453                                                 remove(nonBlankAccnosFiles[h].c_str());
454                                         }
455                                 }else{ hasAccnos = false;  }
456                                 
457                                 if (m->control_pressed) { 
458                                         remove(outputFileName.c_str()); 
459                                         remove(accnosFileName.c_str());
460                                         for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
461                                         delete chimera;
462                                         return 0;
463                                 }
464
465                         }
466
467                 #else
468                         ifstream inFASTA;
469                         openInputFile(candidateFileNames[s], inFASTA);
470                         numSeqs=count(istreambuf_iterator<char>(inFASTA),istreambuf_iterator<char>(), '>');
471                         inFASTA.close();
472                         lines.push_back(new linePair(0, numSeqs));
473                         
474                         driver(lines[0], outputFileName, fastafile, accnosFileName);
475                         
476                         if (m->control_pressed) { 
477                                         remove(outputFileName.c_str()); 
478                                         remove(tempHeader.c_str()); 
479                                         remove(accnosFileName.c_str());
480                                         for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
481                                         delete chimera;
482                                         return 0;
483                         }
484                         
485                         //delete accnos file if its blank 
486                         if (isBlank(accnosFileName)) {  remove(accnosFileName.c_str());  hasAccnos = false; }
487                 #endif
488                 
489                 //m->mothurOut("Output File Names: ");
490                 //if ((filter) && (method == "bellerophon")) { m->mothurOut(
491                 //if (outputDir == "") { fastafile = getRootName(fastafile) + "filter.fasta"; }
492                 //      else                             { fastafile = outputDir + getRootName(getSimpleName(fastafile)) + "filter.fasta"; }
493         
494                 appendOutputFiles(tempHeader, outputFileName);
495         
496                 remove(outputFileName.c_str());
497                 rename(tempHeader.c_str(), outputFileName.c_str());
498         
499                 delete chimera;
500                 
501                 if (method == "chimeracheck") { remove(accnosFileName.c_str());  m->mothurOutEndLine(); m->mothurOut("This method does not determine if a sequence is chimeric, but allows you to make that determination based on the IS values."); m->mothurOutEndLine();  }
502                 
503                 m->mothurOutEndLine();
504                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();
505                 m->mothurOut(outputFileName); m->mothurOutEndLine();    
506                 if (hasAccnos) {  m->mothurOut(accnosFileName); m->mothurOutEndLine();  }
507                 m->mothurOutEndLine();
508
509                 for (int i = 0; i < lines.size(); i++) {  delete lines[i];  }  lines.clear();
510                 
511                 m->mothurOutEndLine(); m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(numSeqs) + " sequences."); m->mothurOutEndLine();
512                 
513                 return 0;
514                 
515         }
516         catch(exception& e) {
517                 m->errorOut(e, "ChimeraSeqsCommand", "execute");
518                 exit(1);
519         }
520 }//**********************************************************************************************************************
521
522 int ChimeraSeqsCommand::driver(linePair* line, string outputFName, string filename, string accnos){
523         try {
524                 ofstream out;
525                 openOutputFile(outputFName, out);
526                 
527                 ofstream out2;
528                 openOutputFile(accnos, out2);
529                 
530                 ifstream inFASTA;
531                 openInputFile(filename, inFASTA);
532
533                 inFASTA.seekg(line->start);
534                 
535                 for(int i=0;i<line->numSeqs;i++){
536                 
537                         if (m->control_pressed) {       return 1;       }
538                 
539                         Sequence* candidateSeq = new Sequence(inFASTA);  gobble(inFASTA);
540                                 
541                         if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
542                                 
543                                 if ((candidateSeq->getAligned().length() != templateSeqsLength) && (method != "chimeracheck")) {  //chimeracheck does not require seqs to be aligned
544                                         m->mothurOut(candidateSeq->getName() + " is not the same length as the template sequences. Skipping."); m->mothurOutEndLine();
545                                 }else{
546                                         //find chimeras
547                                         chimera->getChimeras(candidateSeq);
548                                         
549                                         if (m->control_pressed) {       delete candidateSeq; return 1;  }
550                 
551                                         //print results
552                                         chimera->print(out, out2);
553                                 }
554                         }
555                         delete candidateSeq;
556                         
557                         //report progress
558                         if((i+1) % 100 == 0){   m->mothurOut("Processing sequence: " + toString(i+1)); m->mothurOutEndLine();           }
559                 }
560                 //report progress
561                 if((line->numSeqs) % 100 != 0){ m->mothurOut("Processing sequence: " + toString(line->numSeqs)); m->mothurOutEndLine();         }
562                 
563                 out.close();
564                 out2.close();
565                 inFASTA.close();
566                                 
567                 return 0;
568         }
569         catch(exception& e) {
570                 m->errorOut(e, "ChimeraSeqsCommand", "driver");
571                 exit(1);
572         }
573 }
574
575 /**************************************************************************************************/
576
577 int ChimeraSeqsCommand::createProcesses(string outputFileName, string filename, string accnos) {
578         try {
579 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)
580                 int process = 0;
581                 //              processIDS.resize(0);
582                 
583                 //loop through and create all the processes you want
584                 while (process != processors) {
585                         int pid = fork();
586                         
587                         if (pid > 0) {
588                                 processIDS.push_back(pid);  //create map from line number to pid so you can append files in correct order later
589                                 process++;
590                         }else if (pid == 0){
591                                 driver(lines[process], outputFileName + toString(getpid()) + ".temp", filename, accnos + toString(getpid()) + ".temp");
592                                 exit(0);
593                         }else { m->mothurOut("unable to spawn the necessary processes."); m->mothurOutEndLine(); exit(0); }
594                 }
595                 
596                 //force parent to wait until all the processes are done
597                 for (int i=0;i<processors;i++) { 
598                         int temp = processIDS[i];
599                         wait(&temp);
600                 }
601                 
602                 return 0;
603 #endif          
604         }
605         catch(exception& e) {
606                 m->errorOut(e, "ChimeraSeqsCommand", "createProcesses");
607                 exit(1);
608         }
609 }
610
611 /**************************************************************************************************/
612
613 void ChimeraSeqsCommand::appendOutputFiles(string temp, string filename) {
614         try{
615                 
616                 ofstream output;
617                 ifstream input;
618                 
619                 openOutputFileAppend(temp, output);
620                 openInputFile(filename, input, "noerror");
621                 
622                 while(char c = input.get()){
623                         if(input.eof())         {       break;                  }
624                         else                            {       output << c;    }
625                 }
626                 
627                 input.close();
628                 output.close();
629         }
630         catch(exception& e) {
631                 m->errorOut(e, "ChimeraSeqsCommand", "appendOuputFiles");
632                 exit(1);
633         }
634 }
635 //**********************************************************************************************************************
636
637