/* * Copyright 2011, Ben Langmead * * This file is part of Bowtie 2. * * Bowtie 2 is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Bowtie 2 is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Bowtie 2. If not, see . */ #ifndef ALIGNER_SW_COMMON_H_ #define ALIGNER_SW_COMMON_H_ #include "aligner_result.h" /** * Encapsulates the result of a dynamic programming alignment, including * colorspace alignments. In our case, the result is a combination of: * * 1. All the nucleotide edits * 2. All the "edits" where an ambiguous reference char is resolved to * an unambiguous char. * 3. All the color edits (if applicable) * 4. All the color miscalls (if applicable). This is a subset of 3. * 5. The score of the best alginment * 6. The score of the second-best alignment * * Having scores for the best and second-best alignments gives us an * idea of where gaps may make reassembly beneficial. */ struct SwResult { SwResult() : alres(), sws(0), swcups(0), swrows(0), swskiprows(0), swskip(0), swsucc(0), swfail(0), swbts(0) { } /** * Clear all contents. */ void reset() { sws = swcups = swrows = swskiprows = swskip = swsucc = swfail = swbts = 0; alres.reset(); } /** * Reverse all edit lists. */ void reverse() { alres.reverseEdits(); } /** * Return true iff no result has been installed. */ bool empty() const { return alres.empty(); } #ifndef NDEBUG /** * Check that result is internally consistent. */ bool repOk() const { assert(alres.repOk()); return true; } /** * Check that result is internally consistent w/r/t read. */ bool repOk(const Read& rd) const { assert(alres.repOk(rd)); return true; } #endif AlnRes alres; uint64_t sws; // # DP problems solved uint64_t swcups; // # DP cell updates uint64_t swrows; // # DP row updates uint64_t swskiprows; // # skipped DP row updates (b/c no valid alignments can go thru row) uint64_t swskip; // # DP problems skipped by sse filter uint64_t swsucc; // # DP problems resulting in alignment uint64_t swfail; // # DP problems not resulting in alignment uint64_t swbts; // # DP backtrace steps int nup; // upstream decoded nucleotide; for colorspace reads int ndn; // downstream decoded nucleotide; for colorspace reads }; /** * Encapsulates counters that measure how much work has been done by * the dynamic programming driver and aligner. */ struct SwMetrics { SwMetrics() : mutex_m() { reset(); } void reset() { sws = swcups = swrows = swskiprows = swskip = swsucc = swfail = swbts = sws10 = sws5 = sws3 = rshit = ungapsucc = ungapfail = ungapnodec = 0; exatts = exranges = exrows = exsucc = exooms = 0; mm1atts = mm1ranges = mm1rows = mm1succ = mm1ooms = 0; sdatts = sdranges = sdrows = sdsucc = sdooms = 0; } void init( uint64_t sws_, uint64_t sws10_, uint64_t sws5_, uint64_t sws3_, uint64_t swcups_, uint64_t swrows_, uint64_t swskiprows_, uint64_t swskip_, uint64_t swsucc_, uint64_t swfail_, uint64_t swbts_, uint64_t rshit_, uint64_t ungapsucc_, uint64_t ungapfail_, uint64_t ungapnodec_, uint64_t exatts_, uint64_t exranges_, uint64_t exrows_, uint64_t exsucc_, uint64_t exooms_, uint64_t mm1atts_, uint64_t mm1ranges_, uint64_t mm1rows_, uint64_t mm1succ_, uint64_t mm1ooms_, uint64_t sdatts_, uint64_t sdranges_, uint64_t sdrows_, uint64_t sdsucc_, uint64_t sdooms_) { sws = sws_; sws10 = sws10_; sws5 = sws5_; sws3 = sws3_; swcups = swcups_; swrows = swrows_; swskiprows = swskiprows_; swskip = swskip_; swsucc = swsucc_; swfail = swfail_; swbts = swbts_; ungapsucc = ungapsucc_; ungapfail = ungapfail_; ungapnodec = ungapnodec_; // Exact end-to-end attempts exatts = exatts_; exranges = exranges_; exrows = exrows_; exsucc = exsucc_; exooms = exooms_; // 1-mismatch end-to-end attempts mm1atts = mm1atts_; mm1ranges = mm1ranges_; mm1rows = mm1rows_; mm1succ = mm1succ_; mm1ooms = mm1ooms_; // Seed attempts sdatts = sdatts_; sdranges = sdranges_; sdrows = sdrows_; sdsucc = sdsucc_; sdooms = sdooms_; } /** * Merge (add) the counters in the given SwResult object into this * SwMetrics object. */ void update(const SwResult& r) { sws += r.sws; swcups += r.swcups; swrows += r.swrows; swskiprows += r.swskiprows; swskip += r.swskip; swsucc += r.swsucc; swfail += r.swfail; swbts += r.swbts; } /** * Merge (add) the counters in the given SwMetrics object into this * object. This is the only safe way to update a SwMetrics shared * by multiple threads. */ void merge(const SwMetrics& r, bool getLock = false) { ThreadSafe ts(&mutex_m, getLock); sws += r.sws; sws10 += r.sws10; sws5 += r.sws5; sws3 += r.sws3; swcups += r.swcups; swrows += r.swrows; swskiprows += r.swskiprows; swskip += r.swskip; swsucc += r.swsucc; swfail += r.swfail; swbts += r.swbts; rshit += r.rshit; ungapsucc += r.ungapsucc; ungapfail += r.ungapfail; ungapnodec += r.ungapnodec; exatts += r.exatts; exranges += r.exranges; exrows += r.exrows; exsucc += r.exsucc; exooms += r.exooms; mm1atts += r.mm1atts; mm1ranges += r.mm1ranges; mm1rows += r.mm1rows; mm1succ += r.mm1succ; mm1ooms += r.mm1ooms; sdatts += r.sdatts; sdranges += r.sdranges; sdrows += r.sdrows; sdsucc += r.sdsucc; sdooms += r.sdooms; } void tallyGappedDp(size_t readGaps, size_t refGaps) { size_t mx = max(readGaps, refGaps); if(mx < 10) sws10++; if(mx < 5) sws5++; if(mx < 3) sws3++; } uint64_t sws; // # DP problems solved uint64_t sws10; // # DP problems solved where max gaps < 10 uint64_t sws5; // # DP problems solved where max gaps < 5 uint64_t sws3; // # DP problems solved where max gaps < 3 uint64_t swcups; // # DP cell updates uint64_t swrows; // # DP row updates uint64_t swskiprows; // # skipped DP rows (b/c no valid alns go thru row) uint64_t swskip; // # DP problems skipped by sse filter uint64_t swsucc; // # DP problems resulting in alignment uint64_t swfail; // # DP problems not resulting in alignment uint64_t swbts; // # DP backtrace steps uint64_t rshit; // # DP problems avoided b/c seed hit was redundant uint64_t ungapsucc; // # DP problems avoided b/c seed hit was redundant uint64_t ungapfail; // # DP problems avoided b/c seed hit was redundant uint64_t ungapnodec; // # DP problems avoided b/c seed hit was redundant uint64_t exatts; // total # attempts at exact-hit end-to-end aln uint64_t exranges; // total # ranges returned by exact-hit queries uint64_t exrows; // total # rows returned by exact-hit queries uint64_t exsucc; // exact-hit yielded non-empty result uint64_t exooms; // exact-hit offset memory exhausted uint64_t mm1atts; // total # attempts at 1mm end-to-end aln uint64_t mm1ranges; // total # ranges returned by 1mm-hit queries uint64_t mm1rows; // total # rows returned by 1mm-hit queries uint64_t mm1succ; // 1mm-hit yielded non-empty result uint64_t mm1ooms; // 1mm-hit offset memory exhausted uint64_t sdatts; // total # attempts to find seed alignments uint64_t sdranges; // total # seed-alignment ranges found uint64_t sdrows; // total # seed-alignment rows found uint64_t sdsucc; // # times seed alignment yielded >= 1 hit uint64_t sdooms; // # times an OOM occurred during seed alignment MUTEX_T mutex_m; }; // The various ways that one might backtrack from a later cell (either oall, // rdgap or rfgap) to an earlier cell enum { SW_BT_OALL_DIAG, // from oall cell to oall cell SW_BT_OALL_REF_OPEN, // from oall cell to oall cell SW_BT_OALL_READ_OPEN, // from oall cell to oall cell SW_BT_RDGAP_EXTEND, // from rdgap cell to rdgap cell SW_BT_RFGAP_EXTEND // from rfgap cell to rfgap cell }; #endif /*def ALIGNER_SW_COMMON_H_*/