1 #ifndef TRIMSEQSCOMMAND_H
2 #define TRIMSEQSCOMMAND_H
8 * Created by Pat Schloss on 6/6/09.
9 * Copyright 2009 Patrick D. Schloss. All rights reserved.
14 #include "command.hpp"
15 #include "sequence.hpp"
16 #include "qualityscores.h"
17 #include "trimoligos.h"
18 #include "counttable.h"
21 class TrimSeqsCommand : public Command {
23 TrimSeqsCommand(string);
27 vector<string> setParameters();
28 string getCommandName() { return "trim.seqs"; }
29 string getCommandCategory() { return "Sequence Processing"; }
31 string getHelpString();
32 string getOutputPattern(string);
33 string getCitation() { return "http://www.mothur.org/wiki/Trim.seqs"; }
34 string getDescription() { return "provides the preprocessing features needed to screen and sort pyrosequences"; }
37 void help() { m->mothurOut(getHelpString()); }
41 unsigned long long start;
42 unsigned long long end;
43 linePair(unsigned long long i, unsigned long long j) : start(i), end(j) {}
47 bool getOligos(vector<vector<string> >&, vector<vector<string> >&, vector<vector<string> >&);
48 bool keepFirstTrim(Sequence&, QualityScores&);
49 bool removeLastTrim(Sequence&, QualityScores&);
50 bool cullLength(Sequence&);
51 bool cullHomoP(Sequence&);
52 bool cullAmbigs(Sequence&);
53 string reverseOligo(string);
55 bool abort, createGroup;
56 string fastaFile, oligoFile, qFileName, groupfile, nameFile, countfile, outputDir;
58 bool flip, allFiles, qtrim, keepforward, pairedOligos, reorient, logtransform;
59 int numFPrimers, numRPrimers, numLinkers, numSpacers, maxAmbig, maxHomoP, minLength, maxLength, processors, tdiffs, bdiffs, pdiffs, ldiffs, sdiffs, comboStarts;
60 int qWindowSize, qWindowStep, keepFirst, removeLast;
61 double qRollAverage, qThreshold, qWindowAverage, qAverage;
62 vector<string> revPrimer, outputNames;
63 set<string> filesToRemove;
64 map<int, oligosPair> pairedBarcodes;
65 map<int, oligosPair> pairedPrimers;
66 map<string, int> barcodes;
67 vector<string> groupVector;
68 map<string, int> primers;
69 vector<string> linker;
70 vector<string> spacer;
71 map<string, int> combos;
72 map<string, int> groupToIndex;
73 vector<string> primerNameVector; //needed here?
74 vector<string> barcodeNameVector; //needed here?
75 map<string, int> groupCounts;
76 map<string, string> nameMap;
77 map<string, int> nameCount; //for countfile name -> repCount
78 map<string, string> groupMap; //for countfile name -> group
80 vector<int> processIDS; //processid
81 vector<linePair> lines;
82 vector<linePair> qLines;
84 int driverCreateTrim(string, string, string, string, string, string, string, string, string, string, string, vector<vector<string> >, vector<vector<string> >, vector<vector<string> >, linePair, linePair);
85 int createProcessesCreateTrim(string, string, string, string, string, string, string, string, string, string, string, vector<vector<string> >, vector<vector<string> >, vector<vector<string> >);
86 int setLines(string, string);
89 /**************************************************************************************************/
90 //custom data structure for threads to use.
91 // This is passed by void pointer so it can be any data type
92 // that can be passed using a single void pointer (LPVOID).
94 unsigned long long start, end;
96 string filename, qFileName, trimFileName, scrapFileName, trimQFileName, scrapQFileName, trimNFileName, scrapNFileName, trimCFileName, scrapCFileName, groupFileName, nameFile, countfile;
97 vector<vector<string> > fastaFileNames;
98 vector<vector<string> > qualFileNames;
99 vector<vector<string> > nameFileNames;
100 unsigned long long lineStart, lineEnd, qlineStart, qlineEnd;
101 bool flip, allFiles, qtrim, keepforward, createGroup, pairedOligos, reorient, logtransform;
102 int numFPrimers, numRPrimers, numLinkers, numSpacers, maxAmbig, maxHomoP, minLength, maxLength, tdiffs, bdiffs, pdiffs, ldiffs, sdiffs;
103 int qWindowSize, qWindowStep, keepFirst, removeLast, count;
104 double qRollAverage, qThreshold, qWindowAverage, qAverage;
105 vector<string> revPrimer;
106 map<string, int> barcodes;
107 map<string, int> primers;
108 map<string, int> nameCount;
109 vector<string> linker;
110 vector<string> spacer;
111 map<string, int> combos;
112 vector<string> primerNameVector;
113 vector<string> barcodeNameVector;
114 map<string, int> groupCounts;
115 map<string, string> nameMap;
116 map<string, string> groupMap;
117 map<int, oligosPair> pairedBarcodes;
118 map<int, oligosPair> pairedPrimers;
121 trimData(string fn, string qn, string nf, string cf, string tn, string sn, string tqn, string sqn, string tnn, string snn, string tcn, string scn,string gn, vector<vector<string> > ffn, vector<vector<string> > qfn, vector<vector<string> > nfn, unsigned long long lstart, unsigned long long lend, unsigned long long qstart, unsigned long long qend, MothurOut* mout,
122 int pd, int bd, int ld, int sd, int td, map<string, int> pri, map<string, int> bar, vector<string> revP, vector<string> li, vector<string> spa, map<int, oligosPair> pbr, map<int, oligosPair> ppr, bool po,
123 vector<string> priNameVector, vector<string> barNameVector, bool cGroup, bool aFiles, bool keepF, int keepfi, int removeL,
124 int WindowStep, int WindowSize, int WindowAverage, bool trim, double Threshold, double Average, double RollAverage, bool lt,
125 int minL, int maxA, int maxH, int maxL, bool fli, bool reo, map<string, string> nm, map<string, int> ncount) {
133 scrapQFileName = sqn;
135 scrapNFileName = snn;
137 scrapCFileName = scn;
139 fastaFileNames = ffn;
156 pairedBarcodes = pbr;
158 primers = pri; numFPrimers = primers.size();
159 revPrimer = revP; numRPrimers = revPrimer.size();
160 linker = li; numLinkers = linker.size();
161 spacer = spa; numSpacers = spacer.size();
162 primerNameVector = priNameVector;
163 barcodeNameVector = barNameVector;
165 createGroup = cGroup;
169 removeLast = removeL;
170 qWindowStep = WindowStep;
171 qWindowSize = WindowSize;
172 qWindowAverage = WindowAverage;
174 qThreshold = Threshold;
176 qRollAverage = RollAverage;
188 /**************************************************************************************************/
189 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux) || (__linux__) || (__unix__) || (__unix)
191 static DWORD WINAPI MyTrimThreadFunction(LPVOID lpParam){
192 trimData* pDataArray;
193 pDataArray = (trimData*)lpParam;
196 ofstream trimFASTAFile;
197 pDataArray->m->openOutputFile(pDataArray->trimFileName, trimFASTAFile);
199 ofstream scrapFASTAFile;
200 pDataArray->m->openOutputFile(pDataArray->scrapFileName, scrapFASTAFile);
202 ofstream trimQualFile;
203 ofstream scrapQualFile;
204 if(pDataArray->qFileName != ""){
205 pDataArray->m->openOutputFile(pDataArray->trimQFileName, trimQualFile);
206 pDataArray->m->openOutputFile(pDataArray->scrapQFileName, scrapQualFile);
209 ofstream trimNameFile;
210 ofstream scrapNameFile;
211 if(pDataArray->nameFile != ""){
212 pDataArray->m->openOutputFile(pDataArray->trimNFileName, trimNameFile);
213 pDataArray->m->openOutputFile(pDataArray->scrapNFileName, scrapNameFile);
217 ofstream outGroupsFile;
218 if ((pDataArray->createGroup) && (pDataArray->countfile == "")){ pDataArray->m->openOutputFile(pDataArray->groupFileName, outGroupsFile); }
219 if(pDataArray->allFiles){
220 for (int i = 0; i < pDataArray->fastaFileNames.size(); i++) { //clears old file
221 for (int j = 0; j < pDataArray->fastaFileNames[i].size(); j++) { //clears old file
222 if (pDataArray->fastaFileNames[i][j] != "") {
224 pDataArray->m->openOutputFile(pDataArray->fastaFileNames[i][j], temp); temp.close();
225 if(pDataArray->qFileName != ""){
226 pDataArray->m->openOutputFile(pDataArray->qualFileNames[i][j], temp); temp.close();
229 if(pDataArray->nameFile != ""){
230 pDataArray->m->openOutputFile(pDataArray->nameFileNames[i][j], temp); temp.close();
237 ofstream trimCountFile;
238 ofstream scrapCountFile;
239 if(pDataArray->countfile != ""){
240 pDataArray->m->openOutputFile(pDataArray->trimCFileName, trimCountFile);
241 pDataArray->m->openOutputFile(pDataArray->scrapCFileName, scrapCountFile);
242 if ((pDataArray->lineStart == 0) || (pDataArray->lineStart == 1)) { trimCountFile << "Representative_Sequence\ttotal" << endl; scrapCountFile << "Representative_Sequence\ttotal" << endl; }
246 pDataArray->m->openInputFile(pDataArray->filename, inFASTA);
247 if ((pDataArray->lineStart == 0) || (pDataArray->lineStart == 1)) {
249 }else { //this accounts for the difference in line endings.
250 inFASTA.seekg(pDataArray->lineStart-1); pDataArray->m->gobble(inFASTA);
254 if(pDataArray->qFileName != "") {
255 pDataArray->m->openInputFile(pDataArray->qFileName, qFile);
256 if ((pDataArray->qlineStart == 0) || (pDataArray->qlineStart == 1)) {
258 }else { //this accounts for the difference in line endings.
259 qFile.seekg(pDataArray->qlineStart-1); pDataArray->m->gobble(qFile);
263 TrimOligos* trimOligos = NULL;
264 int numBarcodes = pDataArray->barcodes.size();
265 if (pDataArray->pairedOligos) { trimOligos = new TrimOligos(pDataArray->pdiffs, pDataArray->bdiffs, 0, 0, pDataArray->pairedPrimers, pDataArray->pairedBarcodes); numBarcodes = pDataArray->pairedBarcodes.size(); pDataArray->numFPrimers = pDataArray->pairedPrimers.size(); }
266 else { trimOligos = new TrimOligos(pDataArray->pdiffs, pDataArray->bdiffs, pDataArray->ldiffs, pDataArray->sdiffs, pDataArray->primers, pDataArray->barcodes, pDataArray->revPrimer, pDataArray->linker, pDataArray->spacer); }
268 TrimOligos* rtrimOligos = NULL;
269 if (pDataArray->reorient) {
270 //create reoriented primer and barcode pairs
271 map<int, oligosPair> rpairedPrimers, rpairedBarcodes;
272 for (map<int, oligosPair>::iterator it = pDataArray->pairedPrimers.begin(); it != pDataArray->pairedPrimers.end(); it++) {
273 oligosPair tempPair(trimOligos->reverseOligo((it->second).reverse), (trimOligos->reverseOligo((it->second).forward))); //reversePrimer, rc ForwardPrimer
274 rpairedPrimers[it->first] = tempPair;
276 for (map<int, oligosPair>::iterator it = pDataArray->pairedBarcodes.begin(); it != pDataArray->pairedBarcodes.end(); it++) {
277 oligosPair tempPair(trimOligos->reverseOligo((it->second).reverse), (trimOligos->reverseOligo((it->second).forward))); //reverseBarcode, rc ForwardBarcode
278 rpairedBarcodes[it->first] = tempPair;
281 int index = rpairedBarcodes.size();
282 for (map<string, int>::iterator it = pDataArray->barcodes.begin(); it != pDataArray->barcodes.end(); it++) {
283 oligosPair tempPair("", trimOligos->reverseOligo((it->first))); //reverseBarcode, rc ForwardBarcode
284 rpairedBarcodes[index] = tempPair; index++;
287 index = rpairedPrimers.size();
288 for (map<string, int>::iterator it = pDataArray->primers.begin(); it != pDataArray->primers.end(); it++) {
289 oligosPair tempPair("", trimOligos->reverseOligo((it->first))); //reverseBarcode, rc ForwardBarcode
290 rpairedPrimers[index] = tempPair; index++;
293 rtrimOligos = new TrimOligos(pDataArray->pdiffs, pDataArray->bdiffs, 0, 0, rpairedPrimers, rpairedBarcodes); numBarcodes = rpairedBarcodes.size();
296 pDataArray->count = 0;
297 for(int i = 0; i < pDataArray->lineEnd; i++){ //end is the number of sequences to process
299 if (pDataArray->m->control_pressed) {
300 delete trimOligos; if (pDataArray->reorient) { delete rtrimOligos; }
301 inFASTA.close(); trimFASTAFile.close(); scrapFASTAFile.close();
302 if ((pDataArray->createGroup) && (pDataArray->countfile == "")) { outGroupsFile.close(); }
303 if(pDataArray->qFileName != "") { qFile.close(); scrapQualFile.close(); trimQualFile.close(); }
304 if(pDataArray->nameFile != "") { scrapNameFile.close(); trimNameFile.close(); }
305 if(pDataArray->countfile != "") { scrapCountFile.close(); trimCountFile.close(); }
307 if(pDataArray->qFileName != ""){ qFile.close(); }
312 string trashCode = "";
313 int currentSeqsDiffs = 0;
315 Sequence currSeq(inFASTA); pDataArray->m->gobble(inFASTA);
316 Sequence savedSeq(currSeq.getName(), currSeq.getAligned());
318 QualityScores currQual; QualityScores savedQual;
319 if(pDataArray->qFileName != ""){
320 currQual = QualityScores(qFile); pDataArray->m->gobble(qFile);
321 savedQual.setName(currQual.getName()); savedQual.setScores(currQual.getScores());
325 string origSeq = currSeq.getUnaligned();
329 int barcodeIndex = 0;
332 if(pDataArray->numLinkers != 0){
333 success = trimOligos->stripLinker(currSeq, currQual);
334 if(success > pDataArray->ldiffs) { trashCode += 'k'; }
335 else{ currentSeqsDiffs += success; }
338 if(numBarcodes != 0){
339 success = trimOligos->stripBarcode(currSeq, currQual, barcodeIndex);
340 if(success > pDataArray->bdiffs) { trashCode += 'b'; }
341 else{ currentSeqsDiffs += success; }
344 if(pDataArray->numSpacers != 0){
345 success = trimOligos->stripSpacer(currSeq, currQual);
346 if(success > pDataArray->sdiffs) { trashCode += 's'; }
347 else{ currentSeqsDiffs += success; }
351 if(pDataArray->numFPrimers != 0){
352 success = trimOligos->stripForward(currSeq, currQual, primerIndex, pDataArray->keepforward);
353 if(success > pDataArray->pdiffs) { trashCode += 'f'; }
354 else{ currentSeqsDiffs += success; }
357 if (currentSeqsDiffs > pDataArray->tdiffs) { trashCode += 't'; }
359 if(pDataArray->numRPrimers != 0){
360 success = trimOligos->stripReverse(currSeq, currQual);
361 if(!success) { trashCode += 'r'; }
364 if (pDataArray->reorient && (trashCode != "")) { //if you failed and want to check the reverse
366 string thisTrashCode = "";
367 int thisCurrentSeqsDiffs = 0;
369 int thisBarcodeIndex = 0;
370 int thisPrimerIndex = 0;
372 if(numBarcodes != 0){
373 thisSuccess = rtrimOligos->stripBarcode(savedSeq, savedQual, thisBarcodeIndex);
374 if(thisSuccess > pDataArray->bdiffs) { thisTrashCode += 'b'; }
375 else{ thisCurrentSeqsDiffs += thisSuccess; }
378 if(pDataArray->numFPrimers != 0){
379 thisSuccess = rtrimOligos->stripForward(savedSeq, savedQual, thisPrimerIndex, pDataArray->keepforward);
380 if(thisSuccess > pDataArray->pdiffs) { thisTrashCode += 'f'; }
381 else{ thisCurrentSeqsDiffs += thisSuccess; }
384 if (thisCurrentSeqsDiffs > pDataArray->tdiffs) { thisTrashCode += 't'; }
386 if (thisTrashCode == "") {
387 trashCode = thisTrashCode;
388 success = thisSuccess;
389 currentSeqsDiffs = thisCurrentSeqsDiffs;
390 barcodeIndex = thisBarcodeIndex;
391 primerIndex = thisPrimerIndex;
392 savedSeq.reverseComplement();
393 currSeq.setAligned(savedSeq.getAligned());
394 if(pDataArray->qFileName != ""){
395 savedQual.flipQScores();
396 currQual.setScores(savedQual.getScores());
398 }else { trashCode += "(" + thisTrashCode + ")"; }
402 if(pDataArray->keepFirst != 0){
403 //success = keepFirstTrim(currSeq, currQual);
405 if(currQual.getName() != ""){
406 currQual.trimQScores(-1, pDataArray->keepFirst);
408 currSeq.trim(pDataArray->keepFirst);
411 if(pDataArray->removeLast != 0){
412 //success = removeLastTrim(currSeq, currQual);
414 int length = currSeq.getNumBases() - pDataArray->removeLast;
417 if(currQual.getName() != ""){
418 currQual.trimQScores(-1, length);
420 currSeq.trim(length);
425 if(!success) { trashCode += 'l'; }
429 if(pDataArray->qFileName != ""){
430 int origLength = currSeq.getNumBases();
432 if(pDataArray->qThreshold != 0) { success = currQual.stripQualThreshold(currSeq, pDataArray->qThreshold); }
433 else if(pDataArray->qAverage != 0) { success = currQual.cullQualAverage(currSeq, pDataArray->qAverage, pDataArray->logtransform); }
434 else if(pDataArray->qRollAverage != 0) { success = currQual.stripQualRollingAverage(currSeq, pDataArray->qRollAverage, pDataArray->logtransform); }
435 else if(pDataArray->qWindowAverage != 0){ success = currQual.stripQualWindowAverage(currSeq, pDataArray->qWindowStep, pDataArray->qWindowSize, pDataArray->qWindowAverage, pDataArray->logtransform); }
436 else { success = 1; }
438 //you don't want to trim, if it fails above then scrap it
439 if ((!pDataArray->qtrim) && (origLength != currSeq.getNumBases())) { success = 0; }
441 if(!success) { trashCode += 'q'; }
444 if(pDataArray->minLength > 0 || pDataArray->maxLength > 0){
445 //success = cullLength(currSeq);
446 int length = currSeq.getNumBases();
447 success = 0; //guilty until proven innocent
448 if(length >= pDataArray->minLength && pDataArray->maxLength == 0) { success = 1; }
449 else if(length >= pDataArray->minLength && length <= pDataArray->maxLength) { success = 1; }
450 else { success = 0; }
452 if(!success) { trashCode += 'l'; }
454 if(pDataArray->maxHomoP > 0){
455 //success = cullHomoP(currSeq);
456 int longHomoP = currSeq.getLongHomoPolymer();
457 success = 0; //guilty until proven innocent
458 if(longHomoP <= pDataArray->maxHomoP){ success = 1; }
459 else { success = 0; }
461 if(!success) { trashCode += 'h'; }
463 if(pDataArray->maxAmbig != -1){
464 //success = cullAmbigs(currSeq);
465 int numNs = currSeq.getAmbigBases();
466 success = 0; //guilty until proven innocent
467 if(numNs <= pDataArray->maxAmbig) { success = 1; }
468 else { success = 0; }
469 if(!success) { trashCode += 'n'; }
472 if(pDataArray->flip){ // should go last
473 currSeq.reverseComplement();
474 if(pDataArray->qFileName != ""){
475 currQual.flipQScores();
479 if(trashCode.length() == 0){
480 string thisGroup = "";
481 if (pDataArray->createGroup) {
482 if(numBarcodes != 0){
483 thisGroup = pDataArray->barcodeNameVector[barcodeIndex];
484 if (pDataArray->numFPrimers != 0) {
485 if (pDataArray->primerNameVector[primerIndex] != "") {
486 if(thisGroup != "") {
487 thisGroup += "." + pDataArray->primerNameVector[primerIndex];
489 thisGroup = pDataArray->primerNameVector[primerIndex];
496 int pos = thisGroup.find("ignore");
497 if (pos == string::npos) {
499 currSeq.setAligned(currSeq.getUnaligned());
500 currSeq.printSequence(trimFASTAFile);
502 if(pDataArray->qFileName != ""){
503 currQual.printQScores(trimQualFile);
506 if(pDataArray->nameFile != ""){
507 map<string, string>::iterator itName = pDataArray->nameMap.find(currSeq.getName());
508 if (itName != pDataArray->nameMap.end()) { trimNameFile << itName->first << '\t' << itName->second << endl; }
509 else { pDataArray->m->mothurOut("[ERROR]: " + currSeq.getName() + " is not in your namefile, please correct."); pDataArray->m->mothurOutEndLine(); }
512 int numRedundants = 0;
513 if (pDataArray->countfile != "") {
514 map<string, int>::iterator itCount = pDataArray->nameCount.find(currSeq.getName());
515 if (itCount != pDataArray->nameCount.end()) {
516 trimCountFile << itCount->first << '\t' << itCount->second << endl;
517 numRedundants = itCount->second-1;
518 }else { pDataArray->m->mothurOut("[ERROR]: " + currSeq.getName() + " is not in your count file, please correct."); pDataArray->m->mothurOutEndLine(); }
521 if (pDataArray->createGroup) {
522 if(numBarcodes != 0){
524 if (pDataArray->countfile == "") { outGroupsFile << currSeq.getName() << '\t' << thisGroup << endl; }
525 else { pDataArray->groupMap[currSeq.getName()] = thisGroup; }
527 if (pDataArray->nameFile != "") {
528 map<string, string>::iterator itName = pDataArray->nameMap.find(currSeq.getName());
529 if (itName != pDataArray->nameMap.end()) {
530 vector<string> thisSeqsNames;
531 pDataArray->m->splitAtChar(itName->second, thisSeqsNames, ',');
532 numRedundants = thisSeqsNames.size()-1; //we already include ourselves below
533 for (int k = 1; k < thisSeqsNames.size(); k++) { //start at 1 to skip self
534 outGroupsFile << thisSeqsNames[k] << '\t' << thisGroup << endl;
536 }else { pDataArray->m->mothurOut("[ERROR]: " + currSeq.getName() + " is not in your namefile, please correct."); pDataArray->m->mothurOutEndLine(); }
539 map<string, int>::iterator it = pDataArray->groupCounts.find(thisGroup);
540 if (it == pDataArray->groupCounts.end()) { pDataArray->groupCounts[thisGroup] = 1 + numRedundants; }
541 else { pDataArray->groupCounts[it->first] += (1 + numRedundants); }
546 if(pDataArray->allFiles){
548 pDataArray->m->openOutputFileAppend(pDataArray->fastaFileNames[barcodeIndex][primerIndex], output);
549 currSeq.printSequence(output);
552 if(pDataArray->qFileName != ""){
553 pDataArray->m->openOutputFileAppend(pDataArray->qualFileNames[barcodeIndex][primerIndex], output);
554 currQual.printQScores(output);
558 if(pDataArray->nameFile != ""){
559 map<string, string>::iterator itName = pDataArray->nameMap.find(currSeq.getName());
560 if (itName != pDataArray->nameMap.end()) {
561 pDataArray->m->openOutputFileAppend(pDataArray->nameFileNames[barcodeIndex][primerIndex], output);
562 output << itName->first << '\t' << itName->second << endl;
564 }else { pDataArray->m->mothurOut("[ERROR]: " + currSeq.getName() + " is not in your namefile, please correct."); pDataArray->m->mothurOutEndLine(); }
570 if(pDataArray->nameFile != ""){ //needs to be before the currSeq name is changed
571 map<string, string>::iterator itName = pDataArray->nameMap.find(currSeq.getName());
572 if (itName != pDataArray->nameMap.end()) { scrapNameFile << itName->first << '\t' << itName->second << endl; }
573 else { pDataArray->m->mothurOut("[ERROR]: " + currSeq.getName() + " is not in your namefile, please correct."); pDataArray->m->mothurOutEndLine(); }
575 if (pDataArray->countfile != "") {
576 map<string, int>::iterator itCount = pDataArray->nameCount.find(currSeq.getName());
577 if (itCount != pDataArray->nameCount.end()) {
578 trimCountFile << itCount->first << '\t' << itCount->second << endl;
579 }else { pDataArray->m->mothurOut("[ERROR]: " + currSeq.getName() + " is not in your count file, please correct."); pDataArray->m->mothurOutEndLine(); }
581 currSeq.setName(currSeq.getName() + '|' + trashCode);
582 currSeq.setUnaligned(origSeq);
583 currSeq.setAligned(origSeq);
584 currSeq.printSequence(scrapFASTAFile);
585 if(pDataArray->qFileName != ""){
586 currQual.printQScores(scrapQualFile);
593 if((pDataArray->count) % 1000 == 0){ pDataArray->m->mothurOut(toString(pDataArray->count)); pDataArray->m->mothurOutEndLine(); }
597 if((pDataArray->count) % 1000 != 0){ pDataArray->m->mothurOut(toString(pDataArray->count)); pDataArray->m->mothurOutEndLine(); }
599 if (pDataArray->reorient) { delete rtrimOligos; }
602 trimFASTAFile.close();
603 scrapFASTAFile.close();
604 if (pDataArray->createGroup) { outGroupsFile.close(); }
605 if(pDataArray->qFileName != "") { qFile.close(); scrapQualFile.close(); trimQualFile.close(); }
606 if(pDataArray->nameFile != "") { scrapNameFile.close(); trimNameFile.close(); }
611 catch(exception& e) {
612 pDataArray->m->errorOut(e, "TrimSeqsCommand", "MyTrimThreadFunction");
619 /**************************************************************************************************/