代码拉取完成,页面将自动刷新
/*
* Copyright 2011, Ben Langmead <langmea@cs.jhu.edu>
*
* 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 <http://www.gnu.org/licenses/>.
*/
#ifndef ALIGNER_BT_H_
#define ALIGNER_BT_H_
#include <utility>
#include <stdint.h>
#include "aligner_sw_common.h"
#include "aligner_result.h"
#include "scoring.h"
#include "edit.h"
#include "limit.h"
#include "dp_framer.h"
#include "sse_util.h"
/* Say we've filled in a DP matrix in a cost-only manner, not saving the scores
* for each of the cells. At the end, we obtain a list of candidate cells and
* we'd like to backtrace from them. The per-cell scores are gone, but we have
* to re-create the correct path somehow. Hopefully we can do this without
* recreating most or al of the score matrix, since this takes too much memory.
*
* Approach 1: Naively refill the matrix.
*
* Just refill the matrix, perhaps backwards starting from the backtrace cell.
* Since this involves recreating all or most of the score matrix, this is not
* a good approach.
*
* Approach 2: Naive backtracking.
*
* Conduct a search through the space of possible backtraces, rooted at the
* candidate cell. To speed things along, we can prioritize paths that have a
* high score and that align more characters from the read.
*
* The approach is simple, but it's neither fast nor memory-efficient in
* general.
*
* Approach 3: Refilling with checkpoints.
*
* Refill the matrix "backwards" starting from the candidate cell, but use
* checkpoints to ensure that only a series of relatively small triangles or
* rectangles need to be refilled. The checkpoints must include elements from
* the H, E and F matrices; not just H. After each refill, we backtrace
* through the refilled area, then discard/reuse the fill memory. I call each
* such fill/backtrace a mini-fill/backtrace.
*
* If there's only one path to be found, then this is O(m+n). But what if
* there are many? And what if we would like to avoid paths that overlap in
* one or more cells? There are two ways we can make this more efficient:
*
* 1. Remember the re-calculated E/F/H values and try to retrieve them
* 2. Keep a record of cells that have already been traversed
*
* Legend:
*
* 1: Candidate cell
* 2: Final cell from first mini-fill/backtrace
* 3: Final cell from second mini-fill/backtrace (third not shown)
* +: Checkpointed cell
* *: Cell filled from first or second mini-fill/backtrace
* -: Unfilled cell
*
* ---++--------++--------++----
* --++--------++*-------++-----
* -++--(etc)-++**------++------
* ++--------+3***-----++-------
* +--------++****----++--------
* --------++*****---++--------+
* -------++******--++--------++
* ------++*******-++*-------++-
* -----++********++**------++--
* ----++********2+***-----++---
* ---++--------++****----++----
* --++--------++*****---++-----
* -++--------++*****1--++------
* ++--------++--------++-------
*
* Approach 4: Backtracking with checkpoints.
*
* Conduct a search through the space of possible backtraces, rooted at the
* candidate cell. Use "checkpoints" to prune. That is, when a backtrace
* moves through a cell with a checkpointed score, consider the score
* accumulated so far and the cell's saved score; abort if those two scores
* add to something less than a valid score. Note we're only checkpointing H
* in this case (possibly; see "subtle point"), not E or F.
*
* Subtle point: checkpoint scores are a result of moving forward through
* the matrix whereas backtracking scores result from moving backward. This
* matters becuase the two paths that meet up at a cell might have both
* factored in a gap open penalty for the same gap, in which case we will
* underestimate the overall score and prune a good path. Here are two ideas
* for how to resolve this:
*
* Idea 1: when we combine the forward and backward scores to find an overall
* score, and our backtrack procedure *just* made a horizontal or vertical
* move, add in a "bonus" equal to the gap open penalty of the appropraite
* type (read gap open for horizontal, ref gap open for vertical). This might
* overcompensate, since
*
* Idea 2: keep the E and F values for the checkpoints around, in addition to
* the H values. When it comes time to combine the score from the forward
* and backward paths, we consider the last move we made in the backward
* backtrace. If it's a read gap (horizontal move), then we calculate the
* overall score as:
*
* max(Score-backward + H-forward, Score-backward + E-forward + read-open)
*
* If it's a reference gap (vertical move), then we calculate the overall
* score as:
*
* max(Score-backward + H-forward, Score-backward + F-forward + ref-open)
*
* What does it mean to abort a backtrack? If we're starting a new branch
* and there is a checkpoing in the bottommost cell of the branch, and the
* overall score is less than the target, then we can simply ignore the
* branch. If the checkpoint occurs in the middle of a string of matches, we
* need to curtail the branch such that it doesn't include the checkpointed
* cell and we won't ever try to enter the checkpointed cell, e.g., on a
* mismatch.
*
* Approaches 3 and 4 seem reasonable, and could be combined. For simplicity,
* we implement only approach 4 for now.
*
* Checkpoint information is propagated from the fill process to the backtracer
* via a
*/
enum {
BT_NOT_FOUND = 1, // could not obtain the backtrace because it
// overlapped a previous solution
BT_FOUND, // obtained a valid backtrace
BT_REJECTED_N, // backtrace rejected because it had too many Ns
BT_REJECTED_CORE_DIAG // backtrace rejected because it failed to overlap a
// core diagonal
};
/**
* Parameters for a matrix of potential backtrace problems to solve.
* Encapsulates information about:
*
* The problem given a particular reference substring:
*
* - The query string (nucleotides and qualities)
* - The reference substring (incl. orientation, offset into overall sequence)
* - Checkpoints (i.e. values of matrix cells)
* - Scoring scheme and other thresholds
*
* The problem given a particular reference substring AND a particular row and
* column from which to backtrace:
*
* - The row and column
* - The target score
*/
class BtBranchProblem {
public:
/**
* Create new uninitialized problem.
*/
BtBranchProblem() { reset(); }
/**
* Initialize a new problem.
*/
void initRef(
const char *qry, // query string (along rows)
const char *qual, // query quality string (along rows)
size_t qrylen, // query string (along rows) length
const char *ref, // reference string (along columns)
TRefOff reflen, // in-rectangle reference string length
TRefOff treflen,// total reference string length
TRefId refid, // reference id
TRefOff refoff, // reference offset
bool fw, // orientation of problem
const DPRect* rect, // dynamic programming rectangle filled out
const Checkpointer* cper, // checkpointer
const Scoring *sc, // scoring scheme
size_t nceil) // max # Ns allowed in alignment
{
qry_ = qry;
qual_ = qual;
qrylen_ = qrylen;
ref_ = ref;
reflen_ = reflen;
treflen_ = treflen;
refid_ = refid;
refoff_ = refoff;
fw_ = fw;
rect_ = rect;
cper_ = cper;
sc_ = sc;
nceil_ = nceil;
}
/**
* Initialize a new problem.
*/
void initBt(
size_t row, // row
size_t col, // column
bool fill, // use a filling rather than a backtracking strategy
bool usecp, // use checkpoints to short-circuit while backtracking
TAlScore targ) // target score
{
row_ = row;
col_ = col;
targ_ = targ;
fill_ = fill;
usecp_ = usecp;
if(fill) {
assert(usecp_);
}
}
/**
* Reset to uninitialized state.
*/
void reset() {
qry_ = qual_ = ref_ = NULL;
cper_ = NULL;
rect_ = NULL;
sc_ = NULL;
qrylen_ = reflen_ = treflen_ = refid_ = refoff_ = row_ = col_ = targ_ = nceil_ = 0;
fill_ = fw_ = usecp_ = false;
}
/**
* Return true iff the BtBranchProblem has been initialized.
*/
bool inited() const {
return qry_ != NULL;
}
#ifndef NDEBUG
/**
* Sanity-check the problem.
*/
bool repOk() const {
assert_gt(qrylen_, 0);
assert_gt(reflen_, 0);
assert_gt(treflen_, 0);
assert_lt(row_, qrylen_);
assert_lt((TRefOff)col_, reflen_);
return true;
}
#endif
size_t reflen() const { return reflen_; }
size_t treflen() const { return treflen_; }
protected:
const char *qry_; // query string (along rows)
const char *qual_; // query quality string (along rows)
size_t qrylen_; // query string (along rows) length
const char *ref_; // reference string (along columns)
TRefOff reflen_; // in-rectangle reference string length
TRefOff treflen_;// total reference string length
TRefId refid_; // reference id
TRefOff refoff_; // reference offset
bool fw_; // orientation of problem
const DPRect* rect_; // dynamic programming rectangle filled out
size_t row_; // starting row
size_t col_; // starting column
TAlScore targ_; // target score
const Checkpointer *cper_; // checkpointer
bool fill_; // use mini-fills
bool usecp_; // use checkpointing?
const Scoring *sc_; // scoring scheme
size_t nceil_; // max # Ns allowed in alignment
friend class BtBranch;
friend class BtBranchQ;
friend class BtBranchTracer;
};
/**
* Encapsulates a "branch" which is a diagonal of cells (possibly of length 0)
* in the matrix where all the cells are matches. These stretches are linked
* together by edits to form a full backtrace path through the matrix. Lengths
* are measured w/r/t to the number of rows traversed by the path, so a branch
* that represents a read gap extension could have length = 0.
*
* At the end of the day, the full backtrace path is represented as a list of
* BtBranch's where each BtBranch represents a stretch of matching cells (and
* up to one mismatching cell at its bottom extreme) ending in an edit (or in
* the bottommost row, in which case the edit is uninitialized). Each
* BtBranch's row and col fields indicate the bottommost cell involved in the
* diagonal stretch of matches, and the len_ field indicates the length of the
* stretch of matches. Note that the edits themselves also correspond to
* movement through the matrix.
*
* A related issue is how we record which cells have been visited so that we
* never report a pair of paths both traversing the same (row, col) of the
* overall DP matrix. This gets a little tricky because we have to take into
* account the cells covered by *edits* in addition to the cells covered by the
* stretches of matches. For instance: imagine a mismatch. That takes up a
* cell of the DP matrix, but it may or may not be preceded by a string of
* matches. It's hard to imagine how to represent this unless we let the
* mismatch "count toward" the len_ of the branch and let (row, col) refer to
* the cell where the mismatch occurs.
*
* We need BtBranches to "live forever" so that we can make some BtBranches
* parents of others using parent pointers. For this reason, BtBranch's are
* stored in an EFactory object in the BtBranchTracer class.
*/
class BtBranch {
public:
BtBranch() { reset(); }
BtBranch(
const BtBranchProblem& prob,
size_t parentId,
TAlScore penalty,
TAlScore score_en,
int64_t row,
int64_t col,
Edit e,
int hef,
bool root,
bool extend)
{
init(prob, parentId, penalty, score_en, row, col, e, hef, root, extend);
}
/**
* Reset to uninitialized state.
*/
void reset() {
parentId_ = 0;
score_st_ = score_en_ = len_ = row_ = col_ = 0;
curtailed_ = false;
e_.reset();
}
/**
* Caller gives us score_en, row and col. We figure out score_st and len_
* by comparing characters from the strings.
*/
void init(
const BtBranchProblem& prob,
size_t parentId,
TAlScore penalty,
TAlScore score_en,
int64_t row,
int64_t col,
Edit e,
int hef,
bool root,
bool extend);
/**
* Return true iff this branch ends in a solution to the backtrace problem.
*/
bool isSolution(const BtBranchProblem& prob) const {
const bool end2end = prob.sc_->monotone;
return score_st_ == prob.targ_ && (!end2end || endsInFirstRow());
}
/**
* Return true iff this branch could potentially lead to a valid alignment.
*/
bool isValid(const BtBranchProblem& prob) const {
int64_t scoreFloor = prob.sc_->monotone ? MIN_I64 : 0;
if(score_st_ < scoreFloor) {
// Dipped below the score floor
return false;
}
if(isSolution(prob)) {
// It's a solution, so it's also valid
return true;
}
if((int64_t)len_ > row_) {
// Went all the way to the top row
//assert_leq(score_st_, prob.targ_);
return score_st_ == prob.targ_;
} else {
int64_t match = prob.sc_->match();
int64_t bonusLeft = (row_ + 1 - len_) * match;
return score_st_ + bonusLeft >= prob.targ_;
}
}
/**
* Return true iff this branch overlaps with the given branch.
*/
bool overlap(const BtBranchProblem& prob, const BtBranch& bt) const {
// Calculate this branch's diagonal
assert_lt(row_, (int64_t)prob.qrylen_);
size_t fromend = prob.qrylen_ - row_ - 1;
size_t diag = fromend + col_;
int64_t lo = 0, hi = row_ + 1;
if(len_ == 0) {
lo = row_;
} else {
lo = row_ - (len_ - 1);
}
// Calculate other branch's diagonal
assert_lt(bt.row_, (int64_t)prob.qrylen_);
size_t ofromend = prob.qrylen_ - bt.row_ - 1;
size_t odiag = ofromend + bt.col_;
if(diag != odiag) {
return false;
}
int64_t olo = 0, ohi = bt.row_ + 1;
if(bt.len_ == 0) {
olo = bt.row_;
} else {
olo = bt.row_ - (bt.len_ - 1);
}
int64_t losm = olo, hism = ohi;
if(hi - lo < ohi - olo) {
swap(lo, losm);
swap(hi, hism);
}
if((lo <= losm && hi > losm) || (lo < hism && hi >= hism)) {
return true;
}
return false;
}
/**
* Return true iff this branch is higher priority than the branch 'o'.
*/
bool operator<(const BtBranch& o) const {
// Prioritize uppermost above score
if(uppermostRow() != o.uppermostRow()) {
return uppermostRow() < o.uppermostRow();
}
if(score_st_ != o.score_st_) return score_st_ > o.score_st_;
if(row_ != o.row_) return row_ < o.row_;
if(col_ != o.col_) return col_ > o.col_;
if(parentId_ != o.parentId_) return parentId_ > o.parentId_;
assert(false);
return false;
}
/**
* Return true iff the topmost cell involved in this branch is in the top
* row.
*/
bool endsInFirstRow() const {
assert_leq((int64_t)len_, row_ + 1);
return (int64_t)len_ == row_+1;
}
/**
* Return the uppermost row covered by this branch.
*/
size_t uppermostRow() const {
assert_geq(row_ + 1, (int64_t)len_);
return row_ + 1 - (int64_t)len_;
}
/**
* Return the leftmost column covered by this branch.
*/
size_t leftmostCol() const {
assert_geq(col_ + 1, (int64_t)len_);
return col_ + 1 - (int64_t)len_;
}
#ifndef NDEBUG
/**
* Sanity-check this BtBranch.
*/
bool repOk() const {
assert(root_ || e_.inited());
assert_gt(len_, 0);
assert_geq(col_ + 1, (int64_t)len_);
assert_geq(row_ + 1, (int64_t)len_);
return true;
}
#endif
protected:
// ID of the parent branch.
size_t parentId_;
// Penalty associated with the edit at the bottom of this branch (0 if
// there is no edit)
TAlScore penalty_;
// Score at the beginning of the branch
TAlScore score_st_;
// Score at the end of the branch (taking the edit into account)
TAlScore score_en_;
// Length of the branch. That is, the total number of diagonal cells
// involved in all the matches and in the edit (if any). Should always be
// > 0.
size_t len_;
// The row of the final (bottommost) cell in the branch. This might be the
// bottommost match if the branch has no associated edit. Otherwise, it's
// the cell occupied by the edit.
int64_t row_;
// The column of the final (bottommost) cell in the branch.
int64_t col_;
// The edit at the bottom of the branch. If this is the bottommost branch
// in the alignment and it does not end in an edit, then this remains
// uninitialized.
Edit e_;
// True iff this is the bottommost branch in the alignment. We can't just
// use row_ to tell us this because local alignments don't necessarily end
// in the last row.
bool root_;
bool curtailed_; // true -> pruned at a checkpoint where we otherwise
// would have had a match
friend class BtBranchQ;
friend class BtBranchTracer;
};
/**
* Instantiate and solve best-first branch-based backtraces.
*/
class BtBranchTracer {
public:
explicit BtBranchTracer() :
prob_(), bs_(), seenPaths_(DP_CAT), sawcell_(DP_CAT), doTri_() { }
/**
* Add a branch to the queue.
*/
void add(size_t id) {
assert(!bs_[id].isSolution(prob_));
unsorted_.push_back(make_pair(bs_[id].score_st_, id));
}
/**
* Add a branch to the list of solutions.
*/
void addSolution(size_t id) {
assert(bs_[id].isSolution(prob_));
solutions_.push_back(id);
}
/**
* Given a potential branch to add to the queue, see if we can follow the
* branch a little further first. If it's still valid, or if we reach a
* choice between valid outgoing paths, go ahead and add it to the queue.
*/
void examineBranch(
int64_t row,
int64_t col,
const Edit& e,
TAlScore pen,
TAlScore sc,
size_t parentId);
/**
* Take all possible ways of leaving the given branch and add them to the
* branch queue.
*/
void addOffshoots(size_t bid);
/**
* Get the best branch and remove it from the priority queue.
*/
size_t best(RandomSource& rnd) {
assert(!empty());
flushUnsorted();
assert_gt(sortedSel_ ? sorted1_.size() : sorted2_.size(), cur_);
// Perhaps shuffle everyone who's tied for first?
size_t id = sortedSel_ ? sorted1_[cur_] : sorted2_[cur_];
cur_++;
return id;
}
/**
* Return true iff there are no branches left to try.
*/
bool empty() const {
return size() == 0;
}
/**
* Return the size, i.e. the total number of branches contained.
*/
size_t size() const {
return unsorted_.size() +
(sortedSel_ ? sorted1_.size() : sorted2_.size()) - cur_;
}
/**
* Return true iff there are no solutions left to try.
*/
bool emptySolution() const {
return sizeSolution() == 0;
}
/**
* Return the size of the solution set so far.
*/
size_t sizeSolution() const {
return solutions_.size();
}
/**
* Sort unsorted branches, merge them with master sorted list.
*/
void flushUnsorted();
#ifndef NDEBUG
/**
* Sanity-check the queue.
*/
bool repOk() const {
assert_lt(cur_, (sortedSel_ ? sorted1_.size() : sorted2_.size()));
return true;
}
#endif
/**
* Initialize the tracer with respect to a new read. This involves
* resetting all the state relating to the set of cells already visited
*/
void initRef(
const char* rd, // in: read sequence
const char* qu, // in: quality sequence
size_t rdlen, // in: read sequence length
const char* rf, // in: reference sequence
size_t rflen, // in: in-rectangle reference sequence length
TRefOff trflen, // in: total reference sequence length
TRefId refid, // in: reference id
TRefOff refoff, // in: reference offset
bool fw, // in: orientation
const DPRect *rect, // in: DP rectangle
const Checkpointer *cper, // in: checkpointer
const Scoring& sc, // in: scoring scheme
size_t nceil) // in: N ceiling
{
prob_.initRef(rd, qu, rdlen, rf, rflen, trflen, refid, refoff, fw, rect, cper, &sc, nceil);
const size_t ndiag = rflen + rdlen - 1;
seenPaths_.resize(ndiag);
for(size_t i = 0; i < ndiag; i++) {
seenPaths_[i].clear();
}
// clear each of the per-column sets
if(sawcell_.size() < rflen) {
size_t isz = sawcell_.size();
sawcell_.resize(rflen);
for(size_t i = isz; i < rflen; i++) {
sawcell_[i].setCat(DP_CAT);
}
}
for(size_t i = 0; i < rflen; i++) {
sawcell_[i].setCat(DP_CAT);
sawcell_[i].clear(); // clear the set
}
}
/**
* Initialize with a new backtrace.
*/
void initBt(
TAlScore escore, // in: alignment score
size_t row, // in: start in this row
size_t col, // in: start in this column
bool fill, // in: use mini-filling?
bool usecp, // in: use checkpointing?
bool doTri, // in: triangle-shaped mini-fills?
RandomSource& rnd) // in: random gen, to choose among equal paths
{
prob_.initBt(row, col, fill, usecp, escore);
Edit e; e.reset();
unsorted_.clear();
solutions_.clear();
sorted1_.clear();
sorted2_.clear();
cur_ = 0;
nmm_ = 0; // number of mismatches attempted
nnmm_ = 0; // number of mismatches involving N attempted
nrdop_ = 0; // number of read gap opens attempted
nrfop_ = 0; // number of ref gap opens attempted
nrdex_ = 0; // number of read gap extensions attempted
nrfex_ = 0; // number of ref gap extensions attempted
nmmPrune_ = 0; // number of mismatches attempted
nnmmPrune_ = 0; // number of mismatches involving N attempted
nrdopPrune_ = 0; // number of read gap opens attempted
nrfopPrune_ = 0; // number of ref gap opens attempted
nrdexPrune_ = 0; // number of read gap extensions attempted
nrfexPrune_ = 0; // number of ref gap extensions attempted
row_ = row;
col_ = col;
doTri_ = doTri;
bs_.clear();
if(!prob_.fill_) {
size_t id = bs_.alloc();
bs_[id].init(
prob_,
0, // parent id
0, // penalty
0, // starting score
row, // row
col, // column
e,
0,
true, // this is the root
true); // this should be extend with exact matches
if(bs_[id].isSolution(prob_)) {
addSolution(id);
} else {
add(id);
}
} else {
int64_t row = row_, col = col_;
TAlScore targsc = prob_.targ_;
int hef = 0;
bool done = false, abort = false;
size_t depth = 0;
while(!done && !abort) {
// Accumulate edits as we go. We can do this by adding
// BtBranches to the bs_ structure. Each step of the backtrace
// either involves an edit (thereby starting a new branch) or
// extends the previous branch by one more position.
//
// Note: if the BtBranches are in line, then trySolution can be
// used to populate the SwResult and check for various
// situations where we might reject the alignment (i.e. due to
// a cell having been visited previously).
if(doTri_) {
triangleFill(
row, // row of cell to backtrace from
col, // column of cell to backtrace from
hef, // cell to bt from: H (0), E (1), or F (2)
targsc, // score of cell to backtrace from
prob_.targ_, // score of alignment we're looking for
rnd, // pseudo-random generator
row, // out: row we ended up in after bt
col, // out: column we ended up in after bt
hef, // out: H/E/F after backtrace
targsc, // out: score up to cell we ended up in
done, // out: finished tracing out an alignment?
abort); // out: aborted b/c cell was seen before?
} else {
squareFill(
row, // row of cell to backtrace from
col, // column of cell to backtrace from
hef, // cell to bt from: H (0), E (1), or F (2)
targsc, // score of cell to backtrace from
prob_.targ_, // score of alignment we're looking for
rnd, // pseudo-random generator
row, // out: row we ended up in after bt
col, // out: column we ended up in after bt
hef, // out: H/E/F after backtrace
targsc, // out: score up to cell we ended up in
done, // out: finished tracing out an alignment?
abort); // out: aborted b/c cell was seen before?
}
if(depth >= ndep_.size()) {
ndep_.resize(depth+1);
ndep_[depth] = 1;
} else {
ndep_[depth]++;
}
depth++;
assert((row >= 0 && col >= 0) || done);
}
}
ASSERT_ONLY(seen_.clear());
}
/**
* Get the next valid alignment given the backtrace problem. Return false
* if there is no valid solution, e.g., if
*/
bool nextAlignment(
size_t maxiter,
SwResult& res,
size_t& off,
size_t& nrej,
size_t& niter,
RandomSource& rnd);
/**
* Return true iff this tracer has been initialized
*/
bool inited() const {
return prob_.inited();
}
/**
* Return true iff the mini-fills are triangle-shaped.
*/
bool doTri() const { return doTri_; }
/**
* Fill in a triangle of the DP table and backtrace from the given cell to
* a cell in the previous checkpoint, or to the terminal cell.
*/
void triangleFill(
int64_t rw, // row of cell to backtrace from
int64_t cl, // column of cell to backtrace from
int hef, // cell to backtrace from is H (0), E (1), or F (2)
TAlScore targ, // score of cell to backtrace from
TAlScore targ_final, // score of alignment we're looking for
RandomSource& rnd, // pseudo-random generator
int64_t& row_new, // out: row we ended up in after backtrace
int64_t& col_new, // out: column we ended up in after backtrace
int& hef_new, // out: H/E/F after backtrace
TAlScore& targ_new, // out: score up to cell we ended up in
bool& done, // out: finished tracing out an alignment?
bool& abort); // out: aborted b/c cell was seen before?
/**
* Fill in a square of the DP table and backtrace from the given cell to
* a cell in the previous checkpoint, or to the terminal cell.
*/
void squareFill(
int64_t rw, // row of cell to backtrace from
int64_t cl, // column of cell to backtrace from
int hef, // cell to backtrace from is H (0), E (1), or F (2)
TAlScore targ, // score of cell to backtrace from
TAlScore targ_final, // score of alignment we're looking for
RandomSource& rnd, // pseudo-random generator
int64_t& row_new, // out: row we ended up in after backtrace
int64_t& col_new, // out: column we ended up in after backtrace
int& hef_new, // out: H/E/F after backtrace
TAlScore& targ_new, // out: score up to cell we ended up in
bool& done, // out: finished tracing out an alignment?
bool& abort); // out: aborted b/c cell was seen before?
protected:
/**
* Get the next valid alignment given a backtrace problem. Return false
* if there is no valid solution. Use a backtracking search to find the
* solution. This can be very slow.
*/
bool nextAlignmentBacktrace(
size_t maxiter,
SwResult& res,
size_t& off,
size_t& nrej,
size_t& niter,
RandomSource& rnd);
/**
* Get the next valid alignment given a backtrace problem. Return false
* if there is no valid solution. Use a triangle-fill backtrace to find
* the solution. This is usually fast (it's O(m + n)).
*/
bool nextAlignmentFill(
size_t maxiter,
SwResult& res,
size_t& off,
size_t& nrej,
size_t& niter,
RandomSource& rnd);
/**
* Try all the solutions accumulated so far. Solutions might be rejected
* if they, for instance, overlap a previous solution, have too many Ns,
* fail to overlap a core diagonal, etc.
*/
bool trySolutions(
bool lookForOlap,
SwResult& res,
size_t& off,
size_t& nrej,
RandomSource& rnd,
bool& success);
/**
* See if a given solution branch works as a solution (i.e. doesn't overlap
* another one, have too many Ns, fail to overlap a core diagonal, etc.)
*/
int trySolution(
size_t id,
bool lookForOlap,
SwResult& res,
size_t& off,
size_t& nrej,
RandomSource& rnd);
BtBranchProblem prob_; // problem configuration
EFactory<BtBranch> bs_; // global BtBranch factory
// already reported alignments going through these diagonal segments
ELList<std::pair<size_t, size_t> > seenPaths_;
ELSet<size_t> sawcell_; // cells already backtraced through
EList<std::pair<TAlScore, size_t> > unsorted_; // unsorted list of as-yet-unflished BtBranches
EList<size_t> sorted1_; // list of BtBranch, sorted by score
EList<size_t> sorted2_; // list of BtBranch, sorted by score
EList<size_t> solutions_; // list of solution branches
bool sortedSel_; // true -> 1, false -> 2
size_t cur_; // cursor into sorted list to start from
size_t nmm_; // number of mismatches attempted
size_t nnmm_; // number of mismatches involving N attempted
size_t nrdop_; // number of read gap opens attempted
size_t nrfop_; // number of ref gap opens attempted
size_t nrdex_; // number of read gap extensions attempted
size_t nrfex_; // number of ref gap extensions attempted
size_t nmmPrune_; //
size_t nnmmPrune_; //
size_t nrdopPrune_; //
size_t nrfopPrune_; //
size_t nrdexPrune_; //
size_t nrfexPrune_; //
size_t row_; // row
size_t col_; // column
bool doTri_; // true -> fill in triangles; false -> squares
EList<CpQuad> sq_; // square to fill when doing mini-fills
ELList<CpQuad> tri_; // triangle to fill when doing mini-fills
EList<size_t> ndep_; // # triangles mini-filled at various depths
#ifndef NDEBUG
ESet<size_t> seen_; // seedn branch ids; should never see same twice
#endif
};
#endif /*ndef ALIGNER_BT_H_*/
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。