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