]> git.donarmstrong.com Git - mothur.git/blob - chimeraslayercommand.h
ee43bcbf72a2ca00af3e2270768f34ac1357bb71
[mothur.git] / chimeraslayercommand.h
1 #ifndef CHIMERASLAYERCOMMAND_H
2 #define CHIMERASLAYERCOMMAND_H
3
4 /*
5  *  chimeraslayercommand.h
6  *  Mothur
7  *
8  *  Created by westcott on 3/31/10.
9  *  Copyright 2010 Schloss Lab. All rights reserved.
10  *
11  */
12
13 #include "mothur.h"
14 #include "command.hpp"
15 #include "chimera.h"
16 #include "chimeraslayer.h"
17 #include "sequenceparser.h"
18 #include "sequencecountparser.h"
19
20 /***********************************************************/
21
22 class ChimeraSlayerCommand : public Command {
23 public:
24         ChimeraSlayerCommand(string);
25         ChimeraSlayerCommand();
26         ~ChimeraSlayerCommand() {}
27         
28         vector<string> setParameters();
29         string getCommandName()                 { return "chimera.slayer";              }
30         string getCommandCategory()             { return "Sequence Processing"; }
31         
32         string getHelpString(); 
33     string getOutputPattern(string);    
34         string getCitation() { return "Haas BJ, Gevers D, Earl A, Feldgarden M, Ward DV, Giannokous G, Ciulla D, Tabbaa D, Highlander SK, Sodergren E, Methe B, Desantis TZ, Petrosino JF, Knight R, Birren BW (2011). Chimeric 16S rRNA sequence formation and detection in Sanger and 454-pyrosequenced PCR amplicons. Genome Res  21:494.\nhttp://www.mothur.org/wiki/Chimera.slayer"; }
35         string getDescription()         { return "detect chimeric sequences"; }
36         
37         int execute(); 
38         void help() { m->mothurOut(getHelpString()); }          
39         
40 private:
41
42         struct linePair {
43                 unsigned long long start;
44                 unsigned long long end;
45                 linePair(unsigned long long i, unsigned long long j) : start(i), end(j) {}
46         };
47
48         vector<int> processIDS;   //processid
49         vector<linePair> lines;
50         
51         int driver(linePair, string, string, string, string, map<string, int>&);
52         int createProcesses(string, string, string, string, map<string, int>&);
53         int divideInHalf(Sequence, string&, string&);
54         map<string, int> sortFastaFile(string, string);
55         map<string, int> sortFastaFile(vector<Sequence>&, map<string, string>&, string newFile);
56     int sortFastaFile(vector<Sequence>&, map<string, int>&, string newFile);
57         string getNamesFile(string&);
58         //int setupChimera(string,);
59         int MPIExecute(string, string, string, string, map<string, int>&);
60         int deconvoluteResults(map<string, string>&, string, string, string);
61         map<string, int> priority;
62         int setUpForSelfReference(SequenceParser*&, map<string, string>&, map<string, map<string, int> >&, int);
63     int setUpForSelfReference(SequenceCountParser*&, map<string, string>&, map<string, map<string, int> >&, int);
64         int driverGroups(string, string, string, map<string, map<string, int> >&, map<string, string>&);
65         int createProcessesGroups(string, string, string, map<string, map<string, int> >&, map<string, string>&);
66         int MPIExecuteGroups(string, string, string, map<string, map<string, int> >&, map<string, string>&);
67
68                 
69         #ifdef USE_MPI
70         int driverMPI(int, int, MPI_File&, MPI_File&, MPI_File&, MPI_File&, vector<unsigned long long>&, string, map<string, int>&, bool);
71         #endif
72
73         bool abort, realign, trim, trimera, save, hasName, hasCount, dups;
74         string fastafile, groupfile, templatefile, outputDir, search, namefile, countfile, blastlocation;
75         int processors, window, iters, increment, numwanted, ksize, match, mismatch, parents, minSimilarity, minCoverage, minBS, minSNP, numSeqs, templateSeqsLength;
76         float divR;
77         
78         vector<string> outputNames;
79         vector<string> fastaFileNames;
80         vector<string> nameFileNames;
81         vector<string> groupFileNames;
82         
83 };
84
85 /***********************************************************/
86
87 //custom data structure for threads to use.
88 // This is passed by void pointer so it can be any data type
89 // that can be passed using a single void pointer (LPVOID).
90 struct slayerData {
91         string outputFName; 
92         string fasta; 
93         string accnos;
94         string filename;
95         string templatefile;
96         string search;
97         string blastlocation;
98         bool trimera;
99         bool trim, realign;
100         unsigned long long start;
101         unsigned long long end;
102         int ksize, match, mismatch, window, minSimilarity, minCoverage, minBS, minSNP, parents, iters, increment, numwanted;
103         MothurOut* m;
104         float divR;
105         map<string, int> priority;
106         int count;
107         int numNoParents;
108         int threadId;
109         map<string, map<string, int> > fileToPriority;
110         map<string, string> fileGroup;
111         
112         slayerData(){}
113         slayerData(string o, string fa, string ac, string f, string te, string se, string bl, bool tri, bool trm, bool re, MothurOut* mout, unsigned long long st, unsigned long long en, int ks, int ma, int mis, int win, int minS, int minC, int miBS, int minSN, int par, int it, int inc, int numw, float div, map<string, int> prior, int tid) {
114                 outputFName = o;
115                 fasta = fa;
116                 accnos = ac;
117                 filename = f;
118                 templatefile = te;
119                 search = se;
120                 blastlocation = bl;
121                 trimera = tri;
122                 trim = trm;
123                 realign = re;
124                 m = mout;
125                 start = st;
126                 end = en;
127                 ksize = ks;
128                 match = ma; 
129                 mismatch = mis;
130                 window = win;
131                 minSimilarity = minS;
132                 minCoverage = minC;
133                 minBS = miBS;
134                 minSNP = minSN;
135                 parents = par;
136                 iters = it;
137                 increment = inc;
138                 numwanted = numw;
139                 divR = div;
140                 priority = prior;
141                 threadId = tid;
142                 count = 0;
143                 numNoParents = 0;
144         }
145         slayerData(string o, string fa, string ac, string te, string se, string bl, bool tri, bool trm, bool re, MothurOut* mout, map<string, map<string, int> >& fPriority, map<string, string>& fileG, int ks, int ma, int mis, int win, int minS, int minC, int miBS, int minSN, int par, int it, int inc, int numw, float div, map<string, int> prior, int tid) {
146                 outputFName = o;
147                 fasta = fa;
148                 accnos = ac;
149                 templatefile = te;
150                 search = se;
151                 blastlocation = bl;
152                 trimera = tri;
153                 trim = trm;
154                 realign = re;
155                 m = mout;
156                 fileGroup = fileG;
157                 fileToPriority = fPriority;
158                 ksize = ks;
159                 match = ma; 
160                 mismatch = mis;
161                 window = win;
162                 minSimilarity = minS;
163                 minCoverage = minC;
164                 minBS = miBS;
165                 minSNP = minSN;
166                 parents = par;
167                 iters = it;
168                 increment = inc;
169                 numwanted = numw;
170                 divR = div;
171                 priority = prior;
172                 threadId = tid;
173                 count = 0;
174                 numNoParents = 0;
175         }
176         
177 };
178
179 /**************************************************************************************************/
180 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
181 #else
182 static DWORD WINAPI MySlayerThreadFunction(LPVOID lpParam){ 
183         slayerData* pDataArray;
184         pDataArray = (slayerData*)lpParam;
185         
186         try {
187                 ofstream out;
188                 pDataArray->m->openOutputFile(pDataArray->outputFName, out);
189                 
190                 ofstream out2;
191                 pDataArray->m->openOutputFile(pDataArray->accnos, out2);
192                 
193                 ofstream out3;
194                 if (pDataArray->trim) {  pDataArray->m->openOutputFile(pDataArray->fasta, out3); }
195                 
196                 ifstream inFASTA;
197                 pDataArray->m->openInputFile(pDataArray->filename, inFASTA);
198                 
199                 
200                 
201                 Chimera* chimera;
202                 if (pDataArray->templatefile != "self") { //you want to run slayer with a reference template
203                         chimera = new ChimeraSlayer(pDataArray->filename, pDataArray->templatefile, pDataArray->trim, pDataArray->search, pDataArray->ksize, pDataArray->match, pDataArray->mismatch, pDataArray->window, pDataArray->divR, pDataArray->minSimilarity, pDataArray->minCoverage, pDataArray->minBS, pDataArray->minSNP, pDataArray->parents, pDataArray->iters, pDataArray->increment, pDataArray->numwanted, pDataArray->realign, pDataArray->blastlocation, pDataArray->threadId);     
204                 }else {
205                         chimera = new ChimeraSlayer(pDataArray->filename, pDataArray->templatefile, pDataArray->trim, pDataArray->priority, pDataArray->search, pDataArray->ksize, pDataArray->match, pDataArray->mismatch, pDataArray->window, pDataArray->divR, pDataArray->minSimilarity, pDataArray->minCoverage, pDataArray->minBS, pDataArray->minSNP, pDataArray->parents, pDataArray->iters, pDataArray->increment, pDataArray->numwanted, pDataArray->realign, pDataArray->blastlocation, pDataArray->threadId);       
206                 }
207                 
208                 //print header if you are process 0
209                 if ((pDataArray->start == 0) || (pDataArray->start == 1)) {
210                         chimera->printHeader(out); 
211                         inFASTA.seekg(0);
212                 }else { //this accounts for the difference in line endings. 
213                         inFASTA.seekg(pDataArray->start-1); pDataArray->m->gobble(inFASTA); 
214                 }
215                 
216                 if (pDataArray->m->control_pressed) { out.close(); out2.close(); if (pDataArray->trim) { out3.close(); } inFASTA.close(); delete chimera;  return 0;    }
217                 
218                 if (chimera->getUnaligned()) { 
219                         pDataArray->m->mothurOut("Your template sequences are different lengths, please correct."); pDataArray->m->mothurOutEndLine(); 
220                         out.close(); out2.close(); if (pDataArray->trim) { out3.close(); } inFASTA.close();
221                         delete chimera;
222                         return 0; 
223                 }
224                 int templateSeqsLength = chimera->getLength();
225                 
226                 if (pDataArray->start == 0) { chimera->printHeader(out); }
227                 
228                 pDataArray->count = 0;
229                 for(int i = 0; i < pDataArray->end; i++){
230                         
231                         if (pDataArray->m->control_pressed) {   out.close(); out2.close(); if (pDataArray->trim) { out3.close(); } inFASTA.close(); delete chimera; return 1;   }
232                         
233                         Sequence* candidateSeq = new Sequence(inFASTA);  pDataArray->m->gobble(inFASTA);
234                         string candidateAligned = candidateSeq->getAligned();
235                         
236                         if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
237                                 if (candidateSeq->getAligned().length() != templateSeqsLength) {  
238                                         pDataArray->m->mothurOut(candidateSeq->getName() + " is not the same length as the template sequences. Skipping."); pDataArray->m->mothurOutEndLine();
239                                 }else{
240                                         //find chimeras
241                                         chimera->getChimeras(candidateSeq);
242                                         
243                                         if (pDataArray->m->control_pressed) {   delete candidateSeq; delete chimera; return 1;  }
244                                         
245                                         //if you are not chimeric, then check each half
246                                         data_results wholeResults = chimera->getResults();
247                                         
248                                         //determine if we need to split
249                                         bool isChimeric = false;
250                                         
251                                         if (wholeResults.flag == "yes") {
252                                                 string chimeraFlag = "no";
253                                                 if(  (wholeResults.results[0].bsa >= pDataArray->minBS && wholeResults.results[0].divr_qla_qrb >= pDataArray->divR)
254                                                    ||
255                                                    (wholeResults.results[0].bsb >= pDataArray->minBS && wholeResults.results[0].divr_qlb_qra >= pDataArray->divR) ) { chimeraFlag = "yes"; }
256                                                 
257                                                 
258                                                 if (chimeraFlag == "yes") {     
259                                                         if ((wholeResults.results[0].bsa >= pDataArray->minBS) || (wholeResults.results[0].bsb >= pDataArray->minBS)) { isChimeric = true; }
260                                                 }
261                                         }
262                                         
263                                         if ((!isChimeric) && pDataArray->trimera) {
264                                                 
265                                                 //split sequence in half by bases
266                                                 string leftQuery, rightQuery;
267                                                 Sequence tempSeq(candidateSeq->getName(), candidateAligned);
268                                                 //divideInHalf(tempSeq, leftQuery, rightQuery);
269                                                 string queryUnAligned = tempSeq.getUnaligned();
270                                                 int numBases = int(queryUnAligned.length() * 0.5);
271                                                 
272                                                 string queryAligned = tempSeq.getAligned();
273                                                 leftQuery = tempSeq.getAligned();
274                                                 rightQuery = tempSeq.getAligned();
275                                                 
276                                                 int baseCount = 0;
277                                                 int leftSpot = 0;
278                                                 for (int i = 0; i < queryAligned.length(); i++) {
279                                                         //if you are a base
280                                                         if (isalpha(queryAligned[i])) {         
281                                                                 baseCount++; 
282                                                         }
283                                                         
284                                                         //if you have half
285                                                         if (baseCount >= numBases) {  leftSpot = i; break; } //first half
286                                                 }
287                                                 
288                                                 //blank out right side
289                                                 for (int i = leftSpot; i < leftQuery.length(); i++) { leftQuery[i] = '.'; }
290                                                 
291                                                 //blank out left side
292                                                 for (int i = 0; i < leftSpot; i++) { rightQuery[i] = '.'; }
293                                                 
294                                                 //run chimeraSlayer on each piece
295                                                 Sequence* left = new Sequence(candidateSeq->getName(), leftQuery);
296                                                 Sequence* right = new Sequence(candidateSeq->getName(), rightQuery);
297                                                 
298                                                 //find chimeras
299                                                 chimera->getChimeras(left);
300                                                 data_results leftResults = chimera->getResults();
301                                                 
302                                                 chimera->getChimeras(right);
303                                                 data_results rightResults = chimera->getResults();
304                                                 
305                                                 //if either piece is chimeric then report
306                                                 Sequence trimmed = chimera->print(out, out2, leftResults, rightResults);
307                                                 if (pDataArray->trim) { trimmed.printSequence(out3);  }
308                                                 
309                                                 delete left; delete right;
310                                                 
311                                         }else { //already chimeric
312                                                 //print results
313                                                 Sequence trimmed = chimera->print(out, out2);
314                                                 if (pDataArray->trim) { trimmed.printSequence(out3);  }
315                                         }
316                                         
317                                         
318                                 }
319                                 pDataArray->count++;
320                         }
321                         
322                         delete candidateSeq;
323                         //report progress
324                         if((pDataArray->count) % 100 == 0){     pDataArray->m->mothurOut("Processing sequence: " + toString(pDataArray->count)); pDataArray->m->mothurOutEndLine();             }
325                 }
326                 //report progress
327                 if((pDataArray->count) % 100 != 0){     pDataArray->m->mothurOut("Processing sequence: " + toString(pDataArray->count)); pDataArray->m->mothurOutEndLine();             }
328                 
329                 pDataArray->numNoParents = chimera->getNumNoParents();
330                 if (pDataArray->numNoParents == pDataArray->count) {    pDataArray->m->mothurOut("[WARNING]: megablast returned 0 potential parents for all your sequences. This could be due to formatdb.exe not being setup properly, please check formatdb.log for errors.\n"); }
331
332                 out.close();
333                 out2.close();
334                 if (pDataArray->trim) { out3.close(); }
335                 inFASTA.close();
336                 delete chimera;
337                 
338                 return 0;
339                 
340         }
341         catch(exception& e) {
342                 pDataArray->m->errorOut(e, "ChimeraSlayerCommand", "MySlayerThreadFunction");
343                 exit(1);
344         }
345
346
347 /**************************************************************************************************/
348
349 static DWORD WINAPI MySlayerGroupThreadFunction(LPVOID lpParam){ 
350         slayerData* pDataArray;
351         pDataArray = (slayerData*)lpParam;
352         
353         try {
354                 
355                 int totalSeqs = 0;
356                 
357                 for (map<string, map<string, int> >::iterator itFile = pDataArray->fileToPriority.begin(); itFile != pDataArray->fileToPriority.end(); itFile++) {
358                         
359                         if (pDataArray->m->control_pressed) {  return 0;  }
360                         
361                         int start = time(NULL);
362                         string thisFastaName = itFile->first;
363                         map<string, int> thisPriority = itFile->second;
364                         string thisoutputFileName = pDataArray->m->getRootName(pDataArray->m->getSimpleName(thisFastaName)) + pDataArray->fileGroup[thisFastaName] + "slayer.chimera";
365                         string thisaccnosFileName = pDataArray->m->getRootName(pDataArray->m->getSimpleName(thisFastaName)) + pDataArray->fileGroup[thisFastaName] + "slayer.accnos";
366                         string thistrimFastaFileName = pDataArray->m->getRootName(pDataArray->m->getSimpleName(thisFastaName)) + pDataArray->fileGroup[thisFastaName] + "slayer.fasta";
367                         
368                         pDataArray->m->mothurOutEndLine(); pDataArray->m->mothurOut("Checking sequences from group: " + pDataArray->fileGroup[thisFastaName] + "."); pDataArray->m->mothurOutEndLine(); 
369                 
370                         //int numSeqs = driver(lines[0], thisoutputFileName, thisFastaName, thisaccnosFileName, thistrimFastaFileName, thisPriority);
371                         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
372                         
373                         ofstream out;
374                         pDataArray->m->openOutputFile(thisoutputFileName, out);
375                         
376                         ofstream out2;
377                         pDataArray->m->openOutputFile(thisaccnosFileName, out2);
378                         
379                         ofstream out3;
380                         if (pDataArray->trim) {  pDataArray->m->openOutputFile(thistrimFastaFileName, out3); }
381                         
382                         ifstream inFASTA;
383                         pDataArray->m->openInputFile(thisFastaName, inFASTA);
384                         
385                         Chimera* chimera;
386                         chimera = new ChimeraSlayer(thisFastaName, pDataArray->templatefile, pDataArray->trim, thisPriority, pDataArray->search, pDataArray->ksize, pDataArray->match, pDataArray->mismatch, pDataArray->window, pDataArray->divR, pDataArray->minSimilarity, pDataArray->minCoverage, pDataArray->minBS, pDataArray->minSNP, pDataArray->parents, pDataArray->iters, pDataArray->increment, pDataArray->numwanted, pDataArray->realign, pDataArray->blastlocation, pDataArray->threadId);      
387                         chimera->printHeader(out); 
388                         
389                         int numSeqs = 0;
390                         
391                         if (pDataArray->m->control_pressed) { out.close(); out2.close(); if (pDataArray->trim) { out3.close(); } inFASTA.close(); delete chimera;  return 0;    }
392                         
393                         if (chimera->getUnaligned()) { 
394                                 pDataArray->m->mothurOut("Your template sequences are different lengths, please correct."); pDataArray->m->mothurOutEndLine(); 
395                                 out.close(); out2.close(); if (pDataArray->trim) { out3.close(); } inFASTA.close();
396                                 delete chimera;
397                                 return 0; 
398                         }
399                         int templateSeqsLength = chimera->getLength();
400                         
401                         bool done = false;
402                         while (!done) {
403                                 
404                                 if (pDataArray->m->control_pressed) {   out.close(); out2.close(); if (pDataArray->trim) { out3.close(); } inFASTA.close(); delete chimera; return 1;   }
405                                 
406                                 Sequence* candidateSeq = new Sequence(inFASTA);  pDataArray->m->gobble(inFASTA);
407                                 string candidateAligned = candidateSeq->getAligned();
408                                 
409                                 if (candidateSeq->getName() != "") { //incase there is a commented sequence at the end of a file
410                                         if (candidateSeq->getAligned().length() != templateSeqsLength) {  
411                                                 pDataArray->m->mothurOut(candidateSeq->getName() + " is not the same length as the template sequences. Skipping."); pDataArray->m->mothurOutEndLine();
412                                         }else{
413                                                 //find chimeras
414                                                 chimera->getChimeras(candidateSeq);
415                                                 
416                                                 if (pDataArray->m->control_pressed) {   out.close(); out2.close(); if (pDataArray->trim) { out3.close(); } inFASTA.close(); delete candidateSeq; delete chimera; return 1;      }
417                                                 
418                                                 //if you are not chimeric, then check each half
419                                                 data_results wholeResults = chimera->getResults();
420                                                 
421                                                 //determine if we need to split
422                                                 bool isChimeric = false;
423                                                 
424                                                 if (wholeResults.flag == "yes") {
425                                                         string chimeraFlag = "no";
426                                                         if(  (wholeResults.results[0].bsa >= pDataArray->minBS && wholeResults.results[0].divr_qla_qrb >= pDataArray->divR)
427                                                            ||
428                                                            (wholeResults.results[0].bsb >= pDataArray->minBS && wholeResults.results[0].divr_qlb_qra >= pDataArray->divR) ) { chimeraFlag = "yes"; }
429                                                         
430                                                         
431                                                         if (chimeraFlag == "yes") {     
432                                                                 if ((wholeResults.results[0].bsa >= pDataArray->minBS) || (wholeResults.results[0].bsb >= pDataArray->minBS)) { isChimeric = true; }
433                                                         }
434                                                 }
435                                                 
436                                                 if ((!isChimeric) && pDataArray->trimera) {
437                                                         
438                                                         //split sequence in half by bases
439                                                         string leftQuery, rightQuery;
440                                                         Sequence tempSeq(candidateSeq->getName(), candidateAligned);
441                                                         //divideInHalf(tempSeq, leftQuery, rightQuery);
442                                                         string queryUnAligned = tempSeq.getUnaligned();
443                                                         int numBases = int(queryUnAligned.length() * 0.5);
444                                                         
445                                                         string queryAligned = tempSeq.getAligned();
446                                                         leftQuery = tempSeq.getAligned();
447                                                         rightQuery = tempSeq.getAligned();
448                                                         
449                                                         int baseCount = 0;
450                                                         int leftSpot = 0;
451                                                         for (int i = 0; i < queryAligned.length(); i++) {
452                                                                 //if you are a base
453                                                                 if (isalpha(queryAligned[i])) {         
454                                                                         baseCount++; 
455                                                                 }
456                                                                 
457                                                                 //if you have half
458                                                                 if (baseCount >= numBases) {  leftSpot = i; break; } //first half
459                                                         }
460                                                         
461                                                         //blank out right side
462                                                         for (int i = leftSpot; i < leftQuery.length(); i++) { leftQuery[i] = '.'; }
463                                                         
464                                                         //blank out left side
465                                                         for (int i = 0; i < leftSpot; i++) { rightQuery[i] = '.'; }
466                                                         
467                                                         //run chimeraSlayer on each piece
468                                                         Sequence* left = new Sequence(candidateSeq->getName(), leftQuery);
469                                                         Sequence* right = new Sequence(candidateSeq->getName(), rightQuery);
470                                                         
471                                                         //find chimeras
472                                                         chimera->getChimeras(left);
473                                                         data_results leftResults = chimera->getResults();
474                                                         
475                                                         chimera->getChimeras(right);
476                                                         data_results rightResults = chimera->getResults();
477                                                         
478                                                         //if either piece is chimeric then report
479                                                         Sequence trimmed = chimera->print(out, out2, leftResults, rightResults);
480                                                         if (pDataArray->trim) { trimmed.printSequence(out3);  }
481                                                         
482                                                         delete left; delete right;
483                                                         
484                                                 }else { //already chimeric
485                                                         //print results
486                                                         Sequence trimmed = chimera->print(out, out2);
487                                                         if (pDataArray->trim) { trimmed.printSequence(out3);  }
488                                                 }
489                                                 
490                                                 
491                                         }
492                                         numSeqs++;
493                                 }
494                                 
495                                 delete candidateSeq;
496                                 
497                                 if (inFASTA.eof()) { break; }
498                                 
499                                 //report progress
500                                 if((numSeqs) % 100 == 0){       pDataArray->m->mothurOut("Processing sequence: " + toString(numSeqs)); pDataArray->m->mothurOutEndLine();               }
501                         }
502                         //report progress
503                         if((numSeqs) % 100 != 0){       pDataArray->m->mothurOut("Processing sequence: " + toString(numSeqs)); pDataArray->m->mothurOutEndLine();               }
504                         
505                         pDataArray->numNoParents = chimera->getNumNoParents();
506                         if (pDataArray->numNoParents == numSeqs) {      pDataArray->m->mothurOut("[WARNING]: megablast returned 0 potential parents for all your sequences. This could be due to formatdb.exe not being setup properly, please check formatdb.log for errors.\n"); }
507                         
508                         out.close();
509                         out2.close();
510                         if (pDataArray->trim) { out3.close(); }
511                         inFASTA.close();
512                         delete chimera;
513                         
514                         
515                         ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
516                         
517                         //append files
518                         pDataArray->m->appendFiles(thisoutputFileName, pDataArray->outputFName); pDataArray->m->mothurRemove(thisoutputFileName); 
519                         pDataArray->m->appendFiles(thisaccnosFileName, pDataArray->accnos); pDataArray->m->mothurRemove(thisaccnosFileName);
520                         if (pDataArray->trim) { pDataArray->m->appendFiles(thistrimFastaFileName, pDataArray->fasta); pDataArray->m->mothurRemove(thistrimFastaFileName); }
521                         pDataArray->m->mothurRemove(thisFastaName);
522                         
523                         totalSeqs += numSeqs;
524                         
525                         pDataArray->m->mothurOutEndLine(); pDataArray->m->mothurOut("It took " + toString(time(NULL) - start) + " secs to check " + toString(numSeqs) + " sequences from group " + pDataArray->fileGroup[thisFastaName] + "."); pDataArray->m->mothurOutEndLine();
526                 }
527                 
528                 pDataArray->count = totalSeqs;
529                 
530                 return 0;
531                 
532         }
533         catch(exception& e) {
534                 pDataArray->m->errorOut(e, "ChimeraSlayerCommand", "MySlayerGroupThreadFunction");
535                 exit(1);
536         }
537
538
539 #endif
540
541 /**************************************************************************************************/
542
543
544 #endif
545
546