1 #include "Util.h"
2 #include "Parameters.h"
3 #include "Matcher.h"
4 #include "Debug.h"
5 #include "DBReader.h"
6 #include "DBWriter.h"
7 #include "Orf.h"
8 #include "AlignmentSymmetry.h"
9 #include "Timer.h"
10 #include "IndexReader.h"
11 #include "FileUtil.h"
12
13 #ifdef OPENMP
14 #include <omp.h>
15 #endif
16
17
chainAlignmentHits(std::vector<Matcher::result_t> & results,std::vector<Matcher::result_t> & tmp)18 void chainAlignmentHits(std::vector<Matcher::result_t> &results, std::vector<Matcher::result_t> &tmp) {
19 if(results.size() > 1){
20 std::stable_sort(results.begin(), results.end(), Matcher::compareHitsByPosAndStrand);
21 int prevDiagonal = INT_MAX;
22 Matcher::result_t currRegion;
23 currRegion.dbKey = UINT_MAX;
24 for (size_t resIdx = 0; resIdx < results.size(); resIdx++) {
25 bool currQueryStrang = (results[resIdx].qStartPos > results[resIdx].qEndPos);
26 int qStartPos = std::min(results[resIdx].qStartPos, results[resIdx].qEndPos);
27 int qEndPos = std::max(results[resIdx].qStartPos, results[resIdx].qEndPos);
28 bool currTargetStrand = (results[resIdx].dbStartPos > results[resIdx].dbEndPos);
29 int dbStartPos = std::min(results[resIdx].dbStartPos, results[resIdx].dbEndPos);
30 int dbEndPos = std::max(results[resIdx].dbStartPos, results[resIdx].dbEndPos);
31 std::cout << results[resIdx].dbKey<< "\t" << qStartPos<< "\t" << qEndPos<< "\t" << dbStartPos<< "\t" << dbEndPos << "\t" << std::endl;
32 if(currRegion.dbKey == UINT_MAX){
33 currRegion = results[resIdx];
34 currRegion.qStartPos = qStartPos;
35 currRegion.qEndPos = qEndPos;
36 currRegion.dbStartPos = dbStartPos;
37 currRegion.dbEndPos = dbEndPos;
38 }
39 int currDiagonal = qStartPos - dbStartPos;
40 int nextDiagonal = INT_MAX;
41 bool nextQueryStrand = true;
42 bool nextTargetStrand = true;
43 const bool isDifferentKey = (currRegion.dbKey != results[resIdx].dbKey);
44 const bool isLastElement = (resIdx == results.size() - 1);
45 if (isLastElement == false) {
46 int nextqStartPos = std::min(results[resIdx+1].qStartPos, results[resIdx+1].qEndPos);
47 int nextdbStartPos = std::min(results[resIdx+1].dbStartPos, results[resIdx+1].dbEndPos);
48 nextDiagonal = nextqStartPos - nextdbStartPos;
49 nextQueryStrand = (results[resIdx+1].qStartPos > results[resIdx+1].qEndPos);
50 nextTargetStrand = (results[resIdx+1].dbStartPos > results[resIdx+1].dbEndPos);
51 }
52 const bool queryIsOverlapping = currRegion.qEndPos >= qStartPos && currRegion.qEndPos <= qEndPos;
53 const bool targetIsOverlapping = currRegion.dbEndPos >= dbStartPos && currRegion.dbEndPos <= dbEndPos;
54 const bool sameNextDiagonal = (currDiagonal == nextDiagonal);
55 const bool samePrevDiagonal = (currDiagonal == prevDiagonal);
56 if ( (sameNextDiagonal || samePrevDiagonal ) && queryIsOverlapping && targetIsOverlapping) {
57 currRegion.qStartPos = std::min(currRegion.qStartPos, qStartPos);
58 currRegion.qEndPos = std::max(currRegion.qEndPos, qEndPos);
59 currRegion.dbStartPos = std::min(currRegion.dbStartPos, dbStartPos);
60 currRegion.dbEndPos = std::max(currRegion.dbEndPos, dbEndPos);
61 }
62
63 prevDiagonal = currDiagonal;
64 bool isDifferentNextDiagonal = (nextDiagonal != currDiagonal);
65 bool isDifferentStrand = (nextQueryStrand != currQueryStrang ) || (nextTargetStrand != currTargetStrand );
66 if(isDifferentKey || isLastElement || isDifferentNextDiagonal || isDifferentStrand){
67 if(currQueryStrang){
68 std::swap(currRegion.qStartPos, currRegion.qEndPos);
69 }
70 if(currTargetStrand) {
71 std::swap(currRegion.dbStartPos, currRegion.dbEndPos);
72 }
73 tmp.push_back(currRegion);
74 currRegion.dbKey = UINT_MAX;
75 }
76 }
77 }
78 }
79
80 //
81
82 // We have serval options to consider
83 // Update query and target
84 // Nucl/Nucl
85 // TransNucl/TransNucl
86 // target update
87 // Prot/Nucl
88 // query update
89 // Nucl/Prot
updateOffset(char * data,std::vector<Matcher::result_t> & results,const Orf::SequenceLocation * qloc,IndexReader & tOrfDBr,bool targetNeedsUpdate,bool isNucleotideSearch,int thread_idx)90 void updateOffset(char* data, std::vector<Matcher::result_t> &results, const Orf::SequenceLocation *qloc,
91 IndexReader& tOrfDBr, bool targetNeedsUpdate, bool isNucleotideSearch, int thread_idx) {
92 size_t startPos = results.size();
93 Matcher::readAlignmentResults(results, data, true);
94 size_t endPos = results.size();
95 for (size_t i = startPos; i < endPos; i++) {
96 Matcher::result_t &res = results[i];
97 res.queryOrfStartPos = -1;
98 res.queryOrfEndPos = -1;
99 res.dbOrfStartPos = -1;
100 res.dbOrfEndPos = -1;
101 if (targetNeedsUpdate == true || qloc == NULL) {
102 size_t targetId = tOrfDBr.sequenceReader->getId(res.dbKey);
103 char *header = tOrfDBr.sequenceReader->getData(targetId, thread_idx);
104
105 Orf::SequenceLocation tloc = Orf::parseOrfHeader(header);
106 res.dbKey = (tloc.id != UINT_MAX) ? tloc.id : res.dbKey;
107 size_t from = (tloc.id != UINT_MAX) ? tloc.from : (tloc.strand == Orf::STRAND_MINUS) ? res.dbLen - 1 : 0;
108
109 int dbStartPos = isNucleotideSearch ? res.dbStartPos : res.dbStartPos * 3;
110 int dbEndPos = isNucleotideSearch ? res.dbEndPos : res.dbEndPos * 3;
111 res.dbOrfStartPos = from;
112 res.dbOrfEndPos = tloc.to;
113 if (tloc.strand == Orf::STRAND_MINUS) {
114 res.dbStartPos = from - dbStartPos;
115 res.dbEndPos = from - dbEndPos;
116 // account for last orf
117 // GGCACC
118 // GGCA
119 // ^
120 // last codon position
121 // GGCACC
122 // GGCA
123 // ^
124 // last codon position
125 if(isNucleotideSearch == false){
126 res.dbEndPos = res.dbEndPos - 2;
127 }
128 } else {
129 res.dbStartPos = from + dbStartPos;
130 res.dbEndPos = from + dbEndPos;
131 if(isNucleotideSearch == false){
132 res.dbEndPos = res.dbEndPos + 2;
133 }
134 }
135 }
136 if (qloc != NULL) {
137 int qStartPos = isNucleotideSearch ? res.qStartPos : res.qStartPos * 3;
138 int qEndPos = isNucleotideSearch ? res.qEndPos : res.qEndPos * 3;
139
140 size_t from = (qloc->id != UINT_MAX) ? qloc->from : (qloc->strand == Orf::STRAND_MINUS) ? 0 : res.qLen - 1;
141 res.queryOrfStartPos = from;
142 res.queryOrfEndPos = qloc->to;
143
144 if (qloc->strand == Orf::STRAND_MINUS && qloc->id != UINT_MAX) {
145 res.qStartPos = from - qStartPos;
146 res.qEndPos = from - qEndPos;
147 if(isNucleotideSearch == false){
148 res.qEndPos = res.qEndPos - 2;
149 }
150 } else {
151 res.qStartPos = from + qStartPos;
152 res.qEndPos = from + qEndPos;
153 if(isNucleotideSearch == false){
154 res.qEndPos = res.qEndPos + 2;
155 }
156 }
157 }
158 }
159 }
160
updateLengths(std::vector<Matcher::result_t> & results,unsigned int qSourceLen,IndexReader * tSourceDbr)161 void updateLengths(std::vector<Matcher::result_t> &results, unsigned int qSourceLen, IndexReader* tSourceDbr) {
162 for (size_t i = 0; i < results.size(); ++i) {
163 Matcher::result_t &res = results[i];
164 if (qSourceLen != UINT_MAX) {
165 res.qLen = qSourceLen;
166 }
167 if (tSourceDbr != NULL) {
168 size_t targetId = tSourceDbr->sequenceReader->getId(res.dbKey);
169 res.dbLen = tSourceDbr->sequenceReader->getSeqLen(targetId);
170 }
171 }
172 }
173
offsetalignment(int argc,const char ** argv,const Command & command)174 int offsetalignment(int argc, const char **argv, const Command &command) {
175 Parameters &par = Parameters::getInstance();
176 par.parseParameters(argc, argv, command, true, 0, 0);
177
178 const bool touch = par.preloadMode != Parameters::PRELOAD_MODE_MMAP;
179 int queryDbType = FileUtil::parseDbType(par.db1.c_str());
180 if(Parameters::isEqualDbtype(queryDbType, Parameters::DBTYPE_INDEX_DB)){
181 DBReader<unsigned int> idxdbr(par.db1.c_str(), par.db1Index.c_str(), 1, DBReader<unsigned int>::USE_INDEX | DBReader<unsigned int>::USE_DATA);
182 idxdbr.open(DBReader<unsigned int>::NOSORT);
183 PrefilteringIndexData data = PrefilteringIndexReader::getMetadata(&idxdbr);
184 queryDbType=data.srcSeqType;
185 idxdbr.close();
186 }
187 int targetDbType = FileUtil::parseDbType(par.db3.c_str());
188 if(Parameters::isEqualDbtype(targetDbType, Parameters::DBTYPE_INDEX_DB)){
189 DBReader<unsigned int> idxdbr(par.db3.c_str(), par.db3Index.c_str(), 1, DBReader<unsigned int>::USE_INDEX | DBReader<unsigned int>::USE_DATA);
190 idxdbr.open(DBReader<unsigned int>::NOSORT);
191 PrefilteringIndexData data = PrefilteringIndexReader::getMetadata(&idxdbr);
192 targetDbType=data.srcSeqType;
193 idxdbr.close();
194 }
195
196 IndexReader qOrfDbr(par.db2.c_str(), par.threads, IndexReader::HEADERS, (touch) ? (IndexReader::PRELOAD_INDEX | IndexReader::PRELOAD_DATA) : 0);
197 if (queryDbType == -1) {
198 Debug(Debug::ERROR) << "Please recreate your database or add a .dbtype file to your sequence/profile database.\n";
199 return EXIT_FAILURE;
200 }
201 const bool queryNucl = Parameters::isEqualDbtype(queryDbType, Parameters::DBTYPE_NUCLEOTIDES);
202 IndexReader *qSourceDbr = NULL;
203 if (queryNucl) {
204 qSourceDbr = new IndexReader(par.db1.c_str(), par.threads, IndexReader::SRC_SEQUENCES, (touch) ? (IndexReader::PRELOAD_INDEX) : 0, DBReader<unsigned int>::USE_INDEX);
205 }
206
207 IndexReader * tOrfDbr;
208 bool isSameOrfDB = (par.db2.compare(par.db4) == 0);
209 if(isSameOrfDB){
210 tOrfDbr = &qOrfDbr;
211 }else{
212 tOrfDbr = new IndexReader(par.db4.c_str(), par.threads, IndexReader::HEADERS, (touch) ? (IndexReader::PRELOAD_INDEX | IndexReader::PRELOAD_DATA) : 0);
213 }
214
215 if (targetDbType == -1) {
216 Debug(Debug::ERROR) << "Please recreate your database or add a .dbtype file to your sequence/profile database.\n";
217 return EXIT_FAILURE;
218 }
219 const bool targetNucl = Parameters::isEqualDbtype(targetDbType, Parameters::DBTYPE_NUCLEOTIDES);
220 IndexReader *tSourceDbr = NULL;
221 bool isSameSrcDB = (par.db3.compare(par.db1) == 0);
222 bool isNuclNuclSearch = false;
223 bool isTransNucTransNucSearch = false;
224 bool isTransNuclAln = false;
225 if (targetNucl) {
226 bool seqtargetNuc = true;
227 if(isSameSrcDB){
228 tSourceDbr = qSourceDbr;
229 }else{
230 tSourceDbr = new IndexReader(par.db3.c_str(), par.threads, IndexReader::SRC_SEQUENCES, (touch) ? IndexReader::PRELOAD_INDEX : 0, DBReader<unsigned int>::USE_INDEX );
231 }
232
233 if(Parameters::isEqualDbtype(tSourceDbr->getDbtype(), Parameters::DBTYPE_INDEX_DB)){
234 IndexReader tseqDbr(par.db3, par.threads, IndexReader::SEQUENCES, 0, IndexReader::PRELOAD_INDEX);
235 seqtargetNuc = Parameters::isEqualDbtype(tseqDbr.sequenceReader->getDbtype(), Parameters::DBTYPE_NUCLEOTIDES);
236 isTransNucTransNucSearch = Parameters::isEqualDbtype(tseqDbr.sequenceReader->getDbtype(), Parameters::DBTYPE_AMINO_ACIDS);
237 if(par.searchType == Parameters::SEARCH_TYPE_TRANS_NUCL_ALN){
238 isTransNuclAln = true;
239 }
240 }else{
241 if(par.searchType == Parameters::SEARCH_TYPE_AUTO && (targetNucl == true && queryNucl == true )){
242 Debug(Debug::WARNING) << "Assume that nucleotide search was performed\n";
243 Debug(Debug::WARNING) << "If this is not correct than please provide the parameter --search-type 2 (translated) or 3 (nucleotide)\n";
244 } else if(par.searchType == Parameters::SEARCH_TYPE_TRANSLATED){
245 seqtargetNuc = false;
246 isTransNucTransNucSearch = true;
247 } else if(par.searchType == Parameters::SEARCH_TYPE_NUCLEOTIDES){
248 seqtargetNuc = true;
249 isTransNucTransNucSearch = false;
250 } else if(par.searchType == Parameters::SEARCH_TYPE_TRANS_NUCL_ALN){
251 isTransNuclAln = true;
252 seqtargetNuc = false;
253 isTransNucTransNucSearch = true;
254 }
255 }
256
257 isNuclNuclSearch = (queryNucl && targetNucl && seqtargetNuc);
258 }
259
260 DBReader<unsigned int> alnDbr(par.db5.c_str(), par.db5Index.c_str(), par.threads, DBReader<unsigned int>::USE_INDEX|DBReader<unsigned int>::USE_DATA);
261 alnDbr.open(DBReader<unsigned int>::LINEAR_ACCCESS);
262
263 #ifdef OPENMP
264 unsigned int totalThreads = par.threads;
265 #else
266 unsigned int totalThreads = 1;
267 #endif
268
269 unsigned int localThreads = totalThreads;
270 if (alnDbr.getSize() <= totalThreads) {
271 localThreads = alnDbr.getSize();
272 }
273
274 // Compute mapping from contig -> orf[] from orf[]->contig in headers
275 unsigned int *contigLookup = NULL;
276 unsigned int *contigOffsets = NULL;
277 char *contigExists = NULL;
278 unsigned int maxContigKey = 0;
279 if (Parameters::isEqualDbtype(queryDbType, Parameters::DBTYPE_NUCLEOTIDES)) {
280 Timer timer;
281 Debug(Debug::INFO) << "Computing ORF lookup\n";
282 unsigned int maxOrfKey = alnDbr.getLastKey();
283 unsigned int *orfLookup = new unsigned int[maxOrfKey + 2]();
284 #pragma omp parallel num_threads(localThreads)
285 {
286 unsigned int thread_idx = 0;
287 #ifdef OPENMP
288 thread_idx = (unsigned int) omp_get_thread_num();
289 #endif
290 #pragma omp for schedule(dynamic, 10)
291 for (size_t i = 0; i <= maxOrfKey; ++i) {
292 size_t queryId = qOrfDbr.sequenceReader->getId(i);
293 if (queryId == UINT_MAX) {
294 orfLookup[i] = UINT_MAX;
295 continue;
296 }
297 unsigned int queryKey = qOrfDbr.sequenceReader->getDbKey(queryId);
298 char *header = qOrfDbr.sequenceReader->getData(queryId, thread_idx);
299 Orf::SequenceLocation qloc = Orf::parseOrfHeader(header);
300 unsigned int id = (qloc.id != UINT_MAX) ? qloc.id : queryKey;
301 orfLookup[i] = id;
302 }
303 }
304 Debug(Debug::INFO) << "Computing contig offsets\n";
305 maxContigKey = qSourceDbr->sequenceReader->getLastKey();
306 unsigned int *contigSizes = new unsigned int[maxContigKey + 2]();
307 #pragma omp parallel for schedule(static) num_threads(localThreads)
308 for (size_t i = 0; i <= maxOrfKey ; ++i) {
309 if(orfLookup[i] == UINT_MAX){
310 continue;
311 }
312 __sync_fetch_and_add(&(contigSizes[orfLookup[i]]), 1);
313 }
314 contigOffsets = contigSizes;
315
316 AlignmentSymmetry::computeOffsetFromCounts(contigOffsets, maxContigKey + 1);
317
318 contigExists = new char[maxContigKey + 1]();
319 #pragma omp parallel for schedule(static) num_threads(localThreads)
320 for (size_t i = 0; i < qSourceDbr->sequenceReader->getSize(); ++i) {
321 contigExists[qSourceDbr->sequenceReader->getDbKey(i)] = 1;
322 }
323
324 Debug(Debug::INFO) << "Computing contig lookup\n";
325 contigLookup = new unsigned int[maxOrfKey + 2]();
326 #pragma omp parallel for schedule(static) num_threads(localThreads)
327 for (size_t i = 0; i <= maxOrfKey; ++i) {
328 if(orfLookup[i] == UINT_MAX){
329 continue;
330 }
331 size_t offset = __sync_fetch_and_add(&(contigOffsets[orfLookup[i]]), 1);
332 contigLookup[offset] = i;
333 }
334 delete[] orfLookup;
335
336 for (unsigned int i = maxContigKey + 1; i > 0; --i) {
337 contigOffsets[i] = contigOffsets[i - 1];
338 }
339 contigOffsets[0] = 0;
340 Debug(Debug::INFO) << "Time for contig lookup: " << timer.lap() << "\n";
341 }
342
343 Debug(Debug::INFO) << "Writing results to: " << par.db6 << "\n";
344 DBWriter resultWriter(par.db6.c_str(), par.db6Index.c_str(), localThreads, par.compressed, Parameters::DBTYPE_ALIGNMENT_RES);
345 resultWriter.open();
346
347 size_t entryCount = alnDbr.getSize();
348 if (Parameters::isEqualDbtype(queryDbType, Parameters::DBTYPE_NUCLEOTIDES)) {
349 entryCount = maxContigKey + 1;
350 }
351 Debug::Progress progress(entryCount);
352
353 #pragma omp parallel num_threads(localThreads)
354 {
355 unsigned int thread_idx = 0;
356 #ifdef OPENMP
357 thread_idx = static_cast<unsigned int>(omp_get_thread_num());
358 #endif
359 char buffer[1024 + 32768*4];
360
361 std::string ss;
362 ss.reserve(1024);
363
364 std::vector<Matcher::result_t> results;
365 std::vector<Matcher::result_t> tmp;
366 results.reserve(300);
367 tmp.reserve(300);
368
369 std::string newBacktrace;
370 newBacktrace.reserve(300);
371
372 #pragma omp for schedule(dynamic, 10)
373 for (size_t i = 0; i < entryCount; ++i) {
374 progress.updateProgress();
375 unsigned int queryKey=UINT_MAX;
376 unsigned int qLen = UINT_MAX;
377
378 if (Parameters::isEqualDbtype(queryDbType, Parameters::DBTYPE_NUCLEOTIDES)) {
379 queryKey = i;
380 if (contigExists[i] == 0) {
381 continue;
382 }
383 if (qSourceDbr != NULL) {
384 size_t queryId = qSourceDbr->sequenceReader->getId(queryKey);
385 qLen = qSourceDbr->sequenceReader->getSeqLen(queryId);
386 }
387 unsigned int *orfKeys = &contigLookup[contigOffsets[i]];
388 size_t orfCount = contigOffsets[i + 1] - contigOffsets[i];
389 for (unsigned int j = 0; j < orfCount; ++j) {
390 unsigned int orfKey = orfKeys[j];
391 size_t orfId = alnDbr.getId(orfKey);
392 // this is needed when alnDbr does not contain all identifier of the queryDB
393 if(orfId==UINT_MAX){
394 continue;
395 }
396 char *data = alnDbr.getData(orfId, thread_idx);
397 size_t queryId = qOrfDbr.sequenceReader->getId(orfKey);
398 char *header = qOrfDbr.sequenceReader->getData(queryId, thread_idx);
399 Orf::SequenceLocation qloc = Orf::parseOrfHeader(header);
400 if(qloc.id == UINT_MAX){
401 updateOffset(data, results, NULL, *tOrfDbr, (isNuclNuclSearch||isTransNucTransNucSearch), isNuclNuclSearch, thread_idx);
402 }else{
403 updateOffset(data, results, &qloc, *tOrfDbr, (isNuclNuclSearch||isTransNucTransNucSearch), isNuclNuclSearch, thread_idx);
404 }
405 // do not merge entries
406 if(par.mergeQuery == false){
407 for(size_t i = 0; i < results.size(); i++) {
408 Matcher::result_t &res = results[i];
409 bool hasBacktrace = (res.backtrace.size() > 0);
410 if (isTransNuclAln == true && isNuclNuclSearch == false && isTransNucTransNucSearch == true && hasBacktrace) {
411 newBacktrace.reserve(res.backtrace.length() * 3);
412 Matcher::result_t::protein2nucl(res.backtrace, newBacktrace);
413 res.backtrace = newBacktrace;
414 newBacktrace.clear();
415 }
416 size_t len = Matcher::resultToBuffer(buffer, res, hasBacktrace, false, true);
417 ss.append(buffer, len);
418 }
419 resultWriter.writeData(ss.c_str(), ss.length(), queryKey, thread_idx);
420 results.clear();
421 ss.clear();
422 tmp.clear();
423 }
424 }
425 } else if (Parameters::isEqualDbtype(targetDbType, Parameters::DBTYPE_NUCLEOTIDES)) {
426 queryKey = alnDbr.getDbKey(i);
427 if (qSourceDbr != NULL) {
428 size_t queryId = qSourceDbr->sequenceReader->getId(queryKey);
429 qLen = qSourceDbr->sequenceReader->getSeqLen(queryId);
430 }
431 char *data = alnDbr.getData(i, thread_idx);
432 updateOffset(data, results, NULL, *tOrfDbr, true, isNuclNuclSearch, thread_idx);
433 }
434 if(par.mergeQuery == true){
435 updateLengths(results, qLen, tSourceDbr);
436 if(par.chainAlignment == false){
437 std::stable_sort(results.begin(), results.end(), Matcher::compareHits);
438 for(size_t i = 0; i < results.size(); i++){
439 Matcher::result_t &res = results[i];
440 bool hasBacktrace = (res.backtrace.size() > 0);
441 if (isTransNuclAln == true && isNuclNuclSearch == false && isTransNucTransNucSearch == true && hasBacktrace) {
442 newBacktrace.reserve(res.backtrace.length() * 3);
443 Matcher::result_t::protein2nucl(res.backtrace, newBacktrace);
444 res.backtrace = newBacktrace;
445 newBacktrace.clear();
446 }
447 size_t len = Matcher::resultToBuffer(buffer, res, hasBacktrace, false, true);
448 ss.append(buffer, len);
449 }
450 resultWriter.writeData(ss.c_str(), ss.length(), queryKey, thread_idx);
451 } else if(par.chainAlignment == true){
452 chainAlignmentHits(results, tmp);
453 for(size_t i = 0; i < tmp.size(); i++){
454 Matcher::result_t &res = tmp[i];
455 bool hasBacktrace = (res.backtrace.size() > 0);
456 if (isTransNuclAln == true && isNuclNuclSearch == false && isTransNucTransNucSearch == true && hasBacktrace) {
457 newBacktrace.reserve(res.backtrace.length() * 3);
458 Matcher::result_t::protein2nucl(res.backtrace, newBacktrace);
459 res.backtrace = newBacktrace;
460 newBacktrace.clear();
461 }
462 size_t len = Matcher::resultToBuffer(buffer, res, hasBacktrace, false, true);
463 ss.append(buffer, len);
464 }
465 resultWriter.writeData(ss.c_str(), ss.length(), queryKey, thread_idx);
466 }
467 ss.clear();
468 results.clear();
469 tmp.clear();
470 }
471 }
472 }
473 Debug(Debug::INFO) << "\n";
474 resultWriter.close();
475
476 if (contigLookup != NULL) {
477 delete[] contigLookup;
478 }
479
480 if (contigOffsets != NULL) {
481 delete[] contigOffsets;
482 }
483
484 if (contigExists != NULL) {
485 delete[] contigExists;
486 }
487
488 if(isSameOrfDB == false){
489 delete tOrfDbr;
490 }
491 if(tSourceDbr != NULL){
492 if(isSameSrcDB==false){
493 delete tSourceDbr;
494 }
495 }
496
497 if(qSourceDbr != NULL){
498 delete qSourceDbr;
499 }
500 alnDbr.close();
501
502 return EXIT_SUCCESS;
503 }
504