917 lines
30 KiB
C++
917 lines
30 KiB
C++
/*
|
|
* 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/>.
|
|
*/
|
|
|
|
#include <string>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <limits>
|
|
#include "ds.h"
|
|
#include "aligner_seed_policy.h"
|
|
#include "mem_ids.h"
|
|
|
|
using namespace std;
|
|
|
|
static int parseFuncType(const std::string& otype) {
|
|
string type = otype;
|
|
if(type == "C" || type == "Constant") {
|
|
return SIMPLE_FUNC_CONST;
|
|
} else if(type == "L" || type == "Linear") {
|
|
return SIMPLE_FUNC_LINEAR;
|
|
} else if(type == "S" || type == "Sqrt") {
|
|
return SIMPLE_FUNC_SQRT;
|
|
} else if(type == "G" || type == "Log") {
|
|
return SIMPLE_FUNC_LOG;
|
|
}
|
|
std::cerr << "Error: Bad function type '" << otype.c_str()
|
|
<< "'. Should be C (constant), L (linear), "
|
|
<< "S (square root) or G (natural log)." << std::endl;
|
|
throw 1;
|
|
}
|
|
|
|
#define PARSE_FUNC(fv) { \
|
|
if(ctoks.size() >= 1) { \
|
|
fv.setType(parseFuncType(ctoks[0])); \
|
|
} \
|
|
if(ctoks.size() >= 2) { \
|
|
double co; \
|
|
istringstream tmpss(ctoks[1]); \
|
|
tmpss >> co; \
|
|
fv.setConst(co); \
|
|
} \
|
|
if(ctoks.size() >= 3) { \
|
|
double ce; \
|
|
istringstream tmpss(ctoks[2]); \
|
|
tmpss >> ce; \
|
|
fv.setCoeff(ce); \
|
|
} \
|
|
if(ctoks.size() >= 4) { \
|
|
double mn; \
|
|
istringstream tmpss(ctoks[3]); \
|
|
tmpss >> mn; \
|
|
fv.setMin(mn); \
|
|
} \
|
|
if(ctoks.size() >= 5) { \
|
|
double mx; \
|
|
istringstream tmpss(ctoks[4]); \
|
|
tmpss >> mx; \
|
|
fv.setMin(mx); \
|
|
} \
|
|
}
|
|
|
|
/**
|
|
* Parse alignment policy when provided in this format:
|
|
* <lab>=<val>;<lab>=<val>;<lab>=<val>...
|
|
*
|
|
* And label=value possibilities are:
|
|
*
|
|
* Bonus for a match
|
|
* -----------------
|
|
*
|
|
* MA=xx (default: MA=0, or MA=2 if --local is set)
|
|
*
|
|
* xx = Each position where equal read and reference characters match up
|
|
* in the alignment contriubtes this amount to the total score.
|
|
*
|
|
* Penalty for a mismatch
|
|
* ----------------------
|
|
*
|
|
* MMP={Cxx|Q|RQ} (default: MMP=C6)
|
|
*
|
|
* Cxx = Each mismatch costs xx. If MMP=Cxx is specified, quality
|
|
* values are ignored when assessing penalities for mismatches.
|
|
* Q = Each mismatch incurs a penalty equal to the mismatched base's
|
|
* value.
|
|
* R = Each mismatch incurs a penalty equal to the mismatched base's
|
|
* rounded quality value. Qualities are rounded off to the
|
|
* nearest 10, and qualities greater than 30 are rounded to 30.
|
|
*
|
|
* Penalty for position with N (in either read or reference)
|
|
* ---------------------------------------------------------
|
|
*
|
|
* NP={Cxx|Q|RQ} (default: NP=C1)
|
|
*
|
|
* Cxx = Each alignment position with an N in either the read or the
|
|
* reference costs xx. If NP=Cxx is specified, quality values are
|
|
* ignored when assessing penalities for Ns.
|
|
* Q = Each alignment position with an N in either the read or the
|
|
* reference incurs a penalty equal to the read base's quality
|
|
* value.
|
|
* R = Each alignment position with an N in either the read or the
|
|
* reference incurs a penalty equal to the read base's rounded
|
|
* quality value. Qualities are rounded off to the nearest 10,
|
|
* and qualities greater than 30 are rounded to 30.
|
|
*
|
|
* Penalty for a read gap
|
|
* ----------------------
|
|
*
|
|
* RDG=xx,yy (default: RDG=5,3)
|
|
*
|
|
* xx = Read gap open penalty.
|
|
* yy = Read gap extension penalty.
|
|
*
|
|
* Total cost incurred by a read gap = xx + (yy * gap length)
|
|
*
|
|
* Penalty for a reference gap
|
|
* ---------------------------
|
|
*
|
|
* RFG=xx,yy (default: RFG=5,3)
|
|
*
|
|
* xx = Reference gap open penalty.
|
|
* yy = Reference gap extension penalty.
|
|
*
|
|
* Total cost incurred by a reference gap = xx + (yy * gap length)
|
|
*
|
|
* Minimum score for valid alignment
|
|
* ---------------------------------
|
|
*
|
|
* MIN=xx,yy (defaults: MIN=-0.6,-0.6, or MIN=0.0,0.66 if --local is set)
|
|
*
|
|
* xx,yy = For a read of length N, the total score must be at least
|
|
* xx + (read length * yy) for the alignment to be valid. The
|
|
* total score is the sum of all negative penalties (from
|
|
* mismatches and gaps) and all positive bonuses. The minimum
|
|
* can be negative (and is by default in global alignment mode).
|
|
*
|
|
* Score floor for local alignment
|
|
* -------------------------------
|
|
*
|
|
* FL=xx,yy (defaults: FL=-Infinity,0.0, or FL=0.0,0.0 if --local is set)
|
|
*
|
|
* xx,yy = If a cell in the dynamic programming table has a score less
|
|
* than xx + (read length * yy), then no valid alignment can go
|
|
* through it. Defaults are highly recommended.
|
|
*
|
|
* N ceiling
|
|
* ---------
|
|
*
|
|
* NCEIL=xx,yy (default: NCEIL=0.0,0.15)
|
|
*
|
|
* xx,yy = For a read of length N, the number of alignment
|
|
* positions with an N in either the read or the
|
|
* reference cannot exceed
|
|
* ceiling = xx + (read length * yy). If the ceiling is
|
|
* exceeded, the alignment is considered invalid.
|
|
*
|
|
* Seeds
|
|
* -----
|
|
*
|
|
* SEED=mm,len,ival (default: SEED=0,22)
|
|
*
|
|
* mm = Maximum number of mismatches allowed within a seed.
|
|
* Must be >= 0 and <= 2. Note that 2-mismatch mode is
|
|
* not fully sensitive; i.e. some 2-mismatch seed
|
|
* alignments may be missed.
|
|
* len = Length of seed.
|
|
* ival = Interval between seeds. If not specified, seed
|
|
* interval is determined by IVAL.
|
|
*
|
|
* Seed interval
|
|
* -------------
|
|
*
|
|
* IVAL={L|S|C},xx,yy (default: IVAL=S,1.0,0.0)
|
|
*
|
|
* L = let interval between seeds be a linear function of the
|
|
* read length. xx and yy are the constant and linear
|
|
* coefficients respectively. In other words, the interval
|
|
* equals a * len + b, where len is the read length.
|
|
* Intervals less than 1 are rounded up to 1.
|
|
* S = let interval between seeds be a function of the sqaure
|
|
* root of the read length. xx and yy are the
|
|
* coefficients. In other words, the interval equals
|
|
* a * sqrt(len) + b, where len is the read length.
|
|
* Intervals less than 1 are rounded up to 1.
|
|
* C = Like S but uses cube root of length instead of square
|
|
* root.
|
|
*
|
|
* Example 1:
|
|
*
|
|
* SEED=1,10,5 and read sequence is TGCTATCGTACGATCGTAC:
|
|
*
|
|
* The following seeds are extracted from the forward
|
|
* representation of the read and aligned to the reference
|
|
* allowing up to 1 mismatch:
|
|
*
|
|
* Read: TGCTATCGTACGATCGTACA
|
|
*
|
|
* Seed 1+: TGCTATCGTA
|
|
* Seed 2+: TCGTACGATC
|
|
* Seed 3+: CGATCGTACA
|
|
*
|
|
* ...and the following are extracted from the reverse-complement
|
|
* representation of the read and align to the reference allowing
|
|
* up to 1 mismatch:
|
|
*
|
|
* Seed 1-: TACGATAGCA
|
|
* Seed 2-: GATCGTACGA
|
|
* Seed 3-: TGTACGATCG
|
|
*
|
|
* Example 2:
|
|
*
|
|
* SEED=1,20,20 and read sequence is TGCTATCGTACGATC. The seed
|
|
* length is 20 but the read is only 15 characters long. In this
|
|
* case, Bowtie2 automatically shrinks the seed length to be equal
|
|
* to the read length.
|
|
*
|
|
* Read: TGCTATCGTACGATC
|
|
*
|
|
* Seed 1+: TGCTATCGTACGATC
|
|
* Seed 1-: GATCGTACGATAGCA
|
|
*
|
|
* Example 3:
|
|
*
|
|
* SEED=1,10,10 and read sequence is TGCTATCGTACGATC. Only one seed
|
|
* fits on the read; a second seed would overhang the end of the read
|
|
* by 5 positions. In this case, Bowtie2 extracts one seed.
|
|
*
|
|
* Read: TGCTATCGTACGATC
|
|
*
|
|
* Seed 1+: TGCTATCGTA
|
|
* Seed 1-: TACGATAGCA
|
|
*/
|
|
void SeedAlignmentPolicy::parseString(
|
|
const std::string& s,
|
|
bool local,
|
|
bool noisyHpolymer,
|
|
bool ignoreQuals,
|
|
int& bonusMatchType,
|
|
int& bonusMatch,
|
|
int& penMmcType,
|
|
int& penMmcMax,
|
|
int& penMmcMin,
|
|
int& penScMax,
|
|
int& penScMin,
|
|
int& penNType,
|
|
int& penN,
|
|
int& penRdExConst,
|
|
int& penRfExConst,
|
|
int& penRdExLinear,
|
|
int& penRfExLinear,
|
|
SimpleFunc& costMin,
|
|
SimpleFunc& nCeil,
|
|
bool& nCatPair,
|
|
int& multiseedMms,
|
|
int& multiseedLen,
|
|
SimpleFunc& multiseedIval,
|
|
size_t& failStreak,
|
|
size_t& seedRounds,
|
|
SimpleFunc* penCanIntronLen,
|
|
SimpleFunc* penNoncanIntronLen)
|
|
{
|
|
|
|
bonusMatchType = local ? DEFAULT_MATCH_BONUS_TYPE_LOCAL : DEFAULT_MATCH_BONUS_TYPE;
|
|
bonusMatch = local ? DEFAULT_MATCH_BONUS_LOCAL : DEFAULT_MATCH_BONUS;
|
|
penMmcType = ignoreQuals ? DEFAULT_MM_PENALTY_TYPE_IGNORE_QUALS :
|
|
DEFAULT_MM_PENALTY_TYPE;
|
|
penMmcMax = DEFAULT_MM_PENALTY_MAX;
|
|
penMmcMin = DEFAULT_MM_PENALTY_MIN;
|
|
penNType = DEFAULT_N_PENALTY_TYPE;
|
|
penN = DEFAULT_N_PENALTY;
|
|
|
|
penScMax = DEFAULT_SC_PENALTY_MAX;
|
|
penScMin = DEFAULT_SC_PENALTY_MIN;
|
|
|
|
const double DMAX = std::numeric_limits<double>::max();
|
|
costMin.init(
|
|
local ? SIMPLE_FUNC_LOG : SIMPLE_FUNC_LINEAR,
|
|
local ? DEFAULT_MIN_CONST_LOCAL : 0.0f,
|
|
local ? DEFAULT_MIN_LINEAR_LOCAL : -0.2f);
|
|
nCeil.init(
|
|
SIMPLE_FUNC_LINEAR, 0.0f, DMAX,
|
|
DEFAULT_N_CEIL_CONST, DEFAULT_N_CEIL_LINEAR);
|
|
multiseedIval.init(
|
|
DEFAULT_IVAL, 1.0f, DMAX,
|
|
DEFAULT_IVAL_B, DEFAULT_IVAL_A);
|
|
nCatPair = DEFAULT_N_CAT_PAIR;
|
|
|
|
if(!noisyHpolymer) {
|
|
penRdExConst = DEFAULT_READ_GAP_CONST;
|
|
penRdExLinear = DEFAULT_READ_GAP_LINEAR;
|
|
penRfExConst = DEFAULT_REF_GAP_CONST;
|
|
penRfExLinear = DEFAULT_REF_GAP_LINEAR;
|
|
} else {
|
|
penRdExConst = DEFAULT_READ_GAP_CONST_BADHPOLY;
|
|
penRdExLinear = DEFAULT_READ_GAP_LINEAR_BADHPOLY;
|
|
penRfExConst = DEFAULT_REF_GAP_CONST_BADHPOLY;
|
|
penRfExLinear = DEFAULT_REF_GAP_LINEAR_BADHPOLY;
|
|
}
|
|
|
|
multiseedMms = DEFAULT_SEEDMMS;
|
|
multiseedLen = DEFAULT_SEEDLEN;
|
|
|
|
EList<string> toks(MISC_CAT);
|
|
string tok;
|
|
istringstream ss(s);
|
|
int setting = 0;
|
|
// Get each ;-separated token
|
|
while(getline(ss, tok, ';')) {
|
|
setting++;
|
|
EList<string> etoks(MISC_CAT);
|
|
string etok;
|
|
// Divide into tokens on either side of =
|
|
istringstream ess(tok);
|
|
while(getline(ess, etok, '=')) {
|
|
etoks.push_back(etok);
|
|
}
|
|
// Must be exactly 1 =
|
|
if(etoks.size() != 2) {
|
|
cerr << "Error parsing alignment policy setting " << setting
|
|
<< "; must be bisected by = sign" << endl
|
|
<< "Policy: " << s.c_str() << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
// LHS is tag, RHS value
|
|
string tag = etoks[0], val = etoks[1];
|
|
// Separate value into comma-separated tokens
|
|
EList<string> ctoks(MISC_CAT);
|
|
string ctok;
|
|
istringstream css(val);
|
|
while(getline(css, ctok, ',')) {
|
|
ctoks.push_back(ctok);
|
|
}
|
|
if(ctoks.size() == 0) {
|
|
cerr << "Error parsing alignment policy setting " << setting
|
|
<< "; RHS must have at least 1 token" << endl
|
|
<< "Policy: " << s.c_str() << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
for(size_t i = 0; i < ctoks.size(); i++) {
|
|
if(ctoks[i].length() == 0) {
|
|
cerr << "Error parsing alignment policy setting " << setting
|
|
<< "; token " << i+1 << " on RHS had length=0" << endl
|
|
<< "Policy: " << s.c_str() << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
}
|
|
// Bonus for a match
|
|
// MA=xx (default: MA=0, or MA=10 if --local is set)
|
|
if(tag == "MA") {
|
|
if(ctoks.size() != 1) {
|
|
cerr << "Error parsing alignment policy setting " << setting
|
|
<< "; RHS must have 1 token" << endl
|
|
<< "Policy: " << s.c_str() << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
string tmp = ctoks[0];
|
|
istringstream tmpss(tmp);
|
|
tmpss >> bonusMatch;
|
|
}
|
|
// Scoring for mismatches
|
|
// MMP={Cxx|Q|RQ}
|
|
// Cxx = constant, where constant is integer xx
|
|
// Qxx = equal to quality, scaled
|
|
// R = equal to maq-rounded quality value (rounded to nearest
|
|
// 10, can't be greater than 30)
|
|
else if(tag == "MMP") {
|
|
if(ctoks.size() > 3) {
|
|
cerr << "Error parsing alignment policy setting "
|
|
<< "'" << tag.c_str() << "'"
|
|
<< "; RHS must have at most 3 tokens" << endl
|
|
<< "Policy: '" << s.c_str() << "'" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
if(ctoks[0][0] == 'C') {
|
|
string tmp = ctoks[0].substr(1);
|
|
// Parse constant penalty
|
|
istringstream tmpss(tmp);
|
|
tmpss >> penMmcMax;
|
|
penMmcMin = penMmcMax;
|
|
// Parse constant penalty
|
|
penMmcType = COST_MODEL_CONSTANT;
|
|
} else if(ctoks[0][0] == 'Q') {
|
|
if(ctoks.size() >= 2) {
|
|
string tmp = ctoks[1];
|
|
istringstream tmpss(tmp);
|
|
tmpss >> penMmcMax;
|
|
} else {
|
|
penMmcMax = DEFAULT_MM_PENALTY_MAX;
|
|
}
|
|
if(ctoks.size() >= 3) {
|
|
string tmp = ctoks[2];
|
|
istringstream tmpss(tmp);
|
|
tmpss >> penMmcMin;
|
|
} else {
|
|
penMmcMin = DEFAULT_MM_PENALTY_MIN;
|
|
}
|
|
if(penMmcMin > penMmcMax) {
|
|
cerr << "Error: Maximum mismatch penalty (" << penMmcMax
|
|
<< ") is less than minimum penalty (" << penMmcMin
|
|
<< endl;
|
|
throw 1;
|
|
}
|
|
// Set type to =quality
|
|
penMmcType = COST_MODEL_QUAL;
|
|
} else if(ctoks[0][0] == 'R') {
|
|
// Set type to=Maq-quality
|
|
penMmcType = COST_MODEL_ROUNDED_QUAL;
|
|
} else {
|
|
cerr << "Error parsing alignment policy setting "
|
|
<< "'" << tag.c_str() << "'"
|
|
<< "; RHS must start with C, Q or R" << endl
|
|
<< "Policy: '" << s.c_str() << "'" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
}
|
|
else if(tag == "SCP") {
|
|
if(ctoks.size() > 3) {
|
|
cerr << "Error parsing alignment policy setting "
|
|
<< "'" << tag.c_str() << "'"
|
|
<< "; SCP must have at most 3 tokens" << endl
|
|
<< "Policy: '" << s.c_str() << "'" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
istringstream tmpMax(ctoks[1]);
|
|
tmpMax >> penScMax;
|
|
istringstream tmpMin(ctoks[1]);
|
|
tmpMin >> penScMin;
|
|
if(penScMin > penScMax) {
|
|
cerr << "max (" << penScMax << ") should be >= min (" << penScMin << ")" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
if(penScMin < 1) {
|
|
cerr << "min (" << penScMin << ") should be greater than 0" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
}
|
|
// Scoring for mismatches where read char=N
|
|
// NP={Cxx|Q|RQ}
|
|
// Cxx = constant, where constant is integer xx
|
|
// Q = equal to quality
|
|
// R = equal to maq-rounded quality value (rounded to nearest
|
|
// 10, can't be greater than 30)
|
|
else if(tag == "NP") {
|
|
if(ctoks.size() != 1) {
|
|
cerr << "Error parsing alignment policy setting "
|
|
<< "'" << tag.c_str() << "'"
|
|
<< "; RHS must have 1 token" << endl
|
|
<< "Policy: '" << s.c_str() << "'" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
if(ctoks[0][0] == 'C') {
|
|
string tmp = ctoks[0].substr(1);
|
|
// Parse constant penalty
|
|
istringstream tmpss(tmp);
|
|
tmpss >> penN;
|
|
// Parse constant penalty
|
|
penNType = COST_MODEL_CONSTANT;
|
|
} else if(ctoks[0][0] == 'Q') {
|
|
// Set type to =quality
|
|
penNType = COST_MODEL_QUAL;
|
|
} else if(ctoks[0][0] == 'R') {
|
|
// Set type to=Maq-quality
|
|
penNType = COST_MODEL_ROUNDED_QUAL;
|
|
} else {
|
|
cerr << "Error parsing alignment policy setting "
|
|
<< "'" << tag.c_str() << "'"
|
|
<< "; RHS must start with C, Q or R" << endl
|
|
<< "Policy: '" << s.c_str() << "'" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
}
|
|
// Scoring for read gaps
|
|
// RDG=xx,yy,zz
|
|
// xx = read gap open penalty
|
|
// yy = read gap extension penalty constant coefficient
|
|
// (defaults to open penalty)
|
|
// zz = read gap extension penalty linear coefficient
|
|
// (defaults to 0)
|
|
else if(tag == "RDG") {
|
|
if(ctoks.size() >= 1) {
|
|
istringstream tmpss(ctoks[0]);
|
|
tmpss >> penRdExConst;
|
|
} else {
|
|
penRdExConst = noisyHpolymer ?
|
|
DEFAULT_READ_GAP_CONST_BADHPOLY :
|
|
DEFAULT_READ_GAP_CONST;
|
|
}
|
|
if(ctoks.size() >= 2) {
|
|
istringstream tmpss(ctoks[1]);
|
|
tmpss >> penRdExLinear;
|
|
} else {
|
|
penRdExLinear = noisyHpolymer ?
|
|
DEFAULT_READ_GAP_LINEAR_BADHPOLY :
|
|
DEFAULT_READ_GAP_LINEAR;
|
|
}
|
|
}
|
|
// Scoring for reference gaps
|
|
// RFG=xx,yy,zz
|
|
// xx = ref gap open penalty
|
|
// yy = ref gap extension penalty constant coefficient
|
|
// (defaults to open penalty)
|
|
// zz = ref gap extension penalty linear coefficient
|
|
// (defaults to 0)
|
|
else if(tag == "RFG") {
|
|
if(ctoks.size() >= 1) {
|
|
istringstream tmpss(ctoks[0]);
|
|
tmpss >> penRfExConst;
|
|
} else {
|
|
penRfExConst = noisyHpolymer ?
|
|
DEFAULT_REF_GAP_CONST_BADHPOLY :
|
|
DEFAULT_REF_GAP_CONST;
|
|
}
|
|
if(ctoks.size() >= 2) {
|
|
istringstream tmpss(ctoks[1]);
|
|
tmpss >> penRfExLinear;
|
|
} else {
|
|
penRfExLinear = noisyHpolymer ?
|
|
DEFAULT_REF_GAP_LINEAR_BADHPOLY :
|
|
DEFAULT_REF_GAP_LINEAR;
|
|
}
|
|
}
|
|
// Minimum score as a function of read length
|
|
// MIN=xx,yy
|
|
// xx = constant coefficient
|
|
// yy = linear coefficient
|
|
else if(tag == "MIN") {
|
|
PARSE_FUNC(costMin);
|
|
}
|
|
// Per-read N ceiling as a function of read length
|
|
// NCEIL=xx,yy
|
|
// xx = N ceiling constant coefficient
|
|
// yy = N ceiling linear coefficient (set to 0 if unspecified)
|
|
else if(tag == "NCEIL") {
|
|
PARSE_FUNC(nCeil);
|
|
}
|
|
/*
|
|
* Seeds
|
|
* -----
|
|
*
|
|
* SEED=mm,len,ival (default: SEED=0,22)
|
|
*
|
|
* mm = Maximum number of mismatches allowed within a seed.
|
|
* Must be >= 0 and <= 2. Note that 2-mismatch mode is
|
|
* not fully sensitive; i.e. some 2-mismatch seed
|
|
* alignments may be missed.
|
|
* len = Length of seed.
|
|
* ival = Interval between seeds. If not specified, seed
|
|
* interval is determined by IVAL.
|
|
*/
|
|
else if(tag == "SEED") {
|
|
if(ctoks.size() > 2) {
|
|
cerr << "Error parsing alignment policy setting "
|
|
<< "'" << tag.c_str() << "'; RHS must have 1 or 2 tokens, "
|
|
<< "had " << ctoks.size() << ". "
|
|
<< "Policy: '" << s.c_str() << "'" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
if(ctoks.size() >= 1) {
|
|
istringstream tmpss(ctoks[0]);
|
|
tmpss >> multiseedMms;
|
|
if(multiseedMms > 1) {
|
|
cerr << "Error: -N was set to " << multiseedMms << ", but cannot be set greater than 1" << endl;
|
|
throw 1;
|
|
}
|
|
if(multiseedMms < 0) {
|
|
cerr << "Error: -N was set to a number less than 0 (" << multiseedMms << ")" << endl;
|
|
throw 1;
|
|
}
|
|
}
|
|
if(ctoks.size() >= 2) {
|
|
istringstream tmpss(ctoks[1]);
|
|
tmpss >> multiseedLen;
|
|
} else {
|
|
multiseedLen = DEFAULT_SEEDLEN;
|
|
}
|
|
}
|
|
else if(tag == "SEEDLEN") {
|
|
if(ctoks.size() > 1) {
|
|
cerr << "Error parsing alignment policy setting "
|
|
<< "'" << tag.c_str() << "'; RHS must have 1 token, "
|
|
<< "had " << ctoks.size() << ". "
|
|
<< "Policy: '" << s.c_str() << "'" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
if(ctoks.size() >= 1) {
|
|
istringstream tmpss(ctoks[0]);
|
|
tmpss >> multiseedLen;
|
|
}
|
|
}
|
|
else if(tag == "DPS") {
|
|
if(ctoks.size() > 1) {
|
|
cerr << "Error parsing alignment policy setting "
|
|
<< "'" << tag.c_str() << "'; RHS must have 1 token, "
|
|
<< "had " << ctoks.size() << ". "
|
|
<< "Policy: '" << s.c_str() << "'" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
if(ctoks.size() >= 1) {
|
|
istringstream tmpss(ctoks[0]);
|
|
tmpss >> failStreak;
|
|
}
|
|
}
|
|
else if(tag == "ROUNDS") {
|
|
if(ctoks.size() > 1) {
|
|
cerr << "Error parsing alignment policy setting "
|
|
<< "'" << tag.c_str() << "'; RHS must have 1 token, "
|
|
<< "had " << ctoks.size() << ". "
|
|
<< "Policy: '" << s.c_str() << "'" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
if(ctoks.size() >= 1) {
|
|
istringstream tmpss(ctoks[0]);
|
|
tmpss >> seedRounds;
|
|
}
|
|
}
|
|
/*
|
|
* Seed interval
|
|
* -------------
|
|
*
|
|
* IVAL={L|S|C},a,b (default: IVAL=S,1.0,0.0)
|
|
*
|
|
* L = let interval between seeds be a linear function of the
|
|
* read length. xx and yy are the constant and linear
|
|
* coefficients respectively. In other words, the interval
|
|
* equals a * len + b, where len is the read length.
|
|
* Intervals less than 1 are rounded up to 1.
|
|
* S = let interval between seeds be a function of the sqaure
|
|
* root of the read length. xx and yy are the
|
|
* coefficients. In other words, the interval equals
|
|
* a * sqrt(len) + b, where len is the read length.
|
|
* Intervals less than 1 are rounded up to 1.
|
|
* C = Like S but uses cube root of length instead of square
|
|
* root.
|
|
*/
|
|
else if(tag == "IVAL") {
|
|
PARSE_FUNC(multiseedIval);
|
|
}
|
|
else if(tag == "CANINTRONLEN") {
|
|
assert(penCanIntronLen != NULL);
|
|
PARSE_FUNC((*penCanIntronLen));
|
|
}
|
|
else if(tag == "NONCANINTRONLEN") {
|
|
assert(penNoncanIntronLen != NULL);
|
|
PARSE_FUNC((*penNoncanIntronLen));
|
|
}
|
|
else {
|
|
// Unknown tag
|
|
cerr << "Unexpected alignment policy setting "
|
|
<< "'" << tag.c_str() << "'" << endl
|
|
<< "Policy: '" << s.c_str() << "'" << endl;
|
|
assert(false); throw 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef ALIGNER_SEED_POLICY_MAIN
|
|
int main() {
|
|
|
|
int bonusMatchType;
|
|
int bonusMatch;
|
|
int penMmcType;
|
|
int penMmc;
|
|
int penScMax;
|
|
int penScMin;
|
|
int penNType;
|
|
int penN;
|
|
int penRdExConst;
|
|
int penRfExConst;
|
|
int penRdExLinear;
|
|
int penRfExLinear;
|
|
SimpleFunc costMin;
|
|
SimpleFunc costFloor;
|
|
SimpleFunc nCeil;
|
|
bool nCatPair;
|
|
int multiseedMms;
|
|
int multiseedLen;
|
|
SimpleFunc msIval;
|
|
SimpleFunc posfrac;
|
|
SimpleFunc rowmult;
|
|
uint32_t mhits;
|
|
|
|
{
|
|
cout << "Case 1: Defaults 1 ... ";
|
|
const char *pol = "";
|
|
SeedAlignmentPolicy::parseString(
|
|
string(pol),
|
|
false, // --local?
|
|
false, // noisy homopolymers a la 454?
|
|
false, // ignore qualities?
|
|
bonusMatchType,
|
|
bonusMatch,
|
|
penMmcType,
|
|
penMmc,
|
|
penScMax,
|
|
penScMin,
|
|
penNType,
|
|
penN,
|
|
penRdExConst,
|
|
penRfExConst,
|
|
penRdExLinear,
|
|
penRfExLinear,
|
|
costMin,
|
|
costFloor,
|
|
nCeil,
|
|
nCatPair,
|
|
multiseedMms,
|
|
multiseedLen,
|
|
msIval,
|
|
mhits);
|
|
|
|
assert_eq(DEFAULT_MATCH_BONUS_TYPE, bonusMatchType);
|
|
assert_eq(DEFAULT_MATCH_BONUS, bonusMatch);
|
|
assert_eq(DEFAULT_MM_PENALTY_TYPE, penMmcType);
|
|
assert_eq(DEFAULT_MM_PENALTY_MAX, penMmcMax);
|
|
assert_eq(DEFAULT_MM_PENALTY_MIN, penMmcMin);
|
|
assert_eq(DEFAULT_N_PENALTY_TYPE, penNType);
|
|
assert_eq(DEFAULT_N_PENALTY, penN);
|
|
assert_eq(DEFAULT_MIN_CONST, costMin.getConst());
|
|
assert_eq(DEFAULT_MIN_LINEAR, costMin.getCoeff());
|
|
assert_eq(DEFAULT_FLOOR_CONST, costFloor.getConst());
|
|
assert_eq(DEFAULT_FLOOR_LINEAR, costFloor.getCoeff());
|
|
assert_eq(DEFAULT_N_CEIL_CONST, nCeil.getConst());
|
|
assert_eq(DEFAULT_N_CAT_PAIR, nCatPair);
|
|
|
|
assert_eq(DEFAULT_READ_GAP_CONST, penRdExConst);
|
|
assert_eq(DEFAULT_READ_GAP_LINEAR, penRdExLinear);
|
|
assert_eq(DEFAULT_REF_GAP_CONST, penRfExConst);
|
|
assert_eq(DEFAULT_REF_GAP_LINEAR, penRfExLinear);
|
|
assert_eq(DEFAULT_SEEDMMS, multiseedMms);
|
|
assert_eq(DEFAULT_SEEDLEN, multiseedLen);
|
|
assert_eq(DEFAULT_IVAL, msIval.getType());
|
|
assert_eq(DEFAULT_IVAL_A, msIval.getCoeff());
|
|
assert_eq(DEFAULT_IVAL_B, msIval.getConst());
|
|
|
|
cout << "PASSED" << endl;
|
|
}
|
|
|
|
{
|
|
cout << "Case 2: Defaults 2 ... ";
|
|
const char *pol = "";
|
|
SeedAlignmentPolicy::parseString(
|
|
string(pol),
|
|
false, // --local?
|
|
true, // noisy homopolymers a la 454?
|
|
false, // ignore qualities?
|
|
bonusMatchType,
|
|
bonusMatch,
|
|
penMmcType,
|
|
penMmc,
|
|
|
|
penNType,
|
|
penN,
|
|
penRdExConst,
|
|
penRfExConst,
|
|
penRdExLinear,
|
|
penRfExLinear,
|
|
costMin,
|
|
costFloor,
|
|
nCeil,
|
|
nCatPair,
|
|
multiseedMms,
|
|
multiseedLen,
|
|
msIval,
|
|
mhits);
|
|
|
|
assert_eq(DEFAULT_MATCH_BONUS_TYPE, bonusMatchType);
|
|
assert_eq(DEFAULT_MATCH_BONUS, bonusMatch);
|
|
assert_eq(DEFAULT_MM_PENALTY_TYPE, penMmcType);
|
|
assert_eq(DEFAULT_MM_PENALTY_MAX, penMmc);
|
|
assert_eq(DEFAULT_MM_PENALTY_MIN, penMmc);
|
|
assert_eq(DEFAULT_N_PENALTY_TYPE, penNType);
|
|
assert_eq(DEFAULT_N_PENALTY, penN);
|
|
assert_eq(DEFAULT_MIN_CONST, costMin.getConst());
|
|
assert_eq(DEFAULT_MIN_LINEAR, costMin.getCoeff());
|
|
assert_eq(DEFAULT_FLOOR_CONST, costFloor.getConst());
|
|
assert_eq(DEFAULT_FLOOR_LINEAR, costFloor.getCoeff());
|
|
assert_eq(DEFAULT_N_CEIL_CONST, nCeil.getConst());
|
|
assert_eq(DEFAULT_N_CAT_PAIR, nCatPair);
|
|
|
|
assert_eq(DEFAULT_READ_GAP_CONST_BADHPOLY, penRdExConst);
|
|
assert_eq(DEFAULT_READ_GAP_LINEAR_BADHPOLY, penRdExLinear);
|
|
assert_eq(DEFAULT_REF_GAP_CONST_BADHPOLY, penRfExConst);
|
|
assert_eq(DEFAULT_REF_GAP_LINEAR_BADHPOLY, penRfExLinear);
|
|
assert_eq(DEFAULT_SEEDMMS, multiseedMms);
|
|
assert_eq(DEFAULT_SEEDLEN, multiseedLen);
|
|
assert_eq(DEFAULT_IVAL, msIval.getType());
|
|
assert_eq(DEFAULT_IVAL_A, msIval.getCoeff());
|
|
assert_eq(DEFAULT_IVAL_B, msIval.getConst());
|
|
|
|
cout << "PASSED" << endl;
|
|
}
|
|
|
|
{
|
|
cout << "Case 3: Defaults 3 ... ";
|
|
const char *pol = "";
|
|
SeedAlignmentPolicy::parseString(
|
|
string(pol),
|
|
true, // --local?
|
|
false, // noisy homopolymers a la 454?
|
|
false, // ignore qualities?
|
|
bonusMatchType,
|
|
bonusMatch,
|
|
penMmcType,
|
|
penMmc,
|
|
penNType,
|
|
penN,
|
|
penRdExConst,
|
|
penRfExConst,
|
|
penRdExLinear,
|
|
penRfExLinear,
|
|
costMin,
|
|
costFloor,
|
|
nCeil,
|
|
nCatPair,
|
|
multiseedMms,
|
|
multiseedLen,
|
|
msIval,
|
|
mhits);
|
|
|
|
assert_eq(DEFAULT_MATCH_BONUS_TYPE_LOCAL, bonusMatchType);
|
|
assert_eq(DEFAULT_MATCH_BONUS_LOCAL, bonusMatch);
|
|
assert_eq(DEFAULT_MM_PENALTY_TYPE, penMmcType);
|
|
assert_eq(DEFAULT_MM_PENALTY_MAX, penMmcMax);
|
|
assert_eq(DEFAULT_MM_PENALTY_MIN, penMmcMin);
|
|
assert_eq(DEFAULT_N_PENALTY_TYPE, penNType);
|
|
assert_eq(DEFAULT_N_PENALTY, penN);
|
|
assert_eq(DEFAULT_MIN_CONST_LOCAL, costMin.getConst());
|
|
assert_eq(DEFAULT_MIN_LINEAR_LOCAL, costMin.getCoeff());
|
|
assert_eq(DEFAULT_FLOOR_CONST_LOCAL, costFloor.getConst());
|
|
assert_eq(DEFAULT_FLOOR_LINEAR_LOCAL, costFloor.getCoeff());
|
|
assert_eq(DEFAULT_N_CEIL_CONST, nCeil.getConst());
|
|
assert_eq(DEFAULT_N_CEIL_LINEAR, nCeil.getCoeff());
|
|
assert_eq(DEFAULT_N_CAT_PAIR, nCatPair);
|
|
|
|
assert_eq(DEFAULT_READ_GAP_CONST, penRdExConst);
|
|
assert_eq(DEFAULT_READ_GAP_LINEAR, penRdExLinear);
|
|
assert_eq(DEFAULT_REF_GAP_CONST, penRfExConst);
|
|
assert_eq(DEFAULT_REF_GAP_LINEAR, penRfExLinear);
|
|
assert_eq(DEFAULT_SEEDMMS, multiseedMms);
|
|
assert_eq(DEFAULT_SEEDLEN, multiseedLen);
|
|
assert_eq(DEFAULT_IVAL, msIval.getType());
|
|
assert_eq(DEFAULT_IVAL_A, msIval.getCoeff());
|
|
assert_eq(DEFAULT_IVAL_B, msIval.getConst());
|
|
|
|
cout << "PASSED" << endl;
|
|
}
|
|
|
|
{
|
|
cout << "Case 4: Simple string 1 ... ";
|
|
const char *pol = "MMP=C44;MA=4;RFG=24,12;FL=C,8;RDG=2;NP=C4;MIN=C,7";
|
|
SeedAlignmentPolicy::parseString(
|
|
string(pol),
|
|
true, // --local?
|
|
false, // noisy homopolymers a la 454?
|
|
false, // ignore qualities?
|
|
bonusMatchType,
|
|
bonusMatch,
|
|
penMmcType,
|
|
penMmc,
|
|
penNType,
|
|
penN,
|
|
penRdExConst,
|
|
penRfExConst,
|
|
penRdExLinear,
|
|
penRfExLinear,
|
|
costMin,
|
|
costFloor,
|
|
nCeil,
|
|
nCatPair,
|
|
multiseedMms,
|
|
multiseedLen,
|
|
msIval,
|
|
mhits);
|
|
|
|
assert_eq(COST_MODEL_CONSTANT, bonusMatchType);
|
|
assert_eq(4, bonusMatch);
|
|
assert_eq(COST_MODEL_CONSTANT, penMmcType);
|
|
assert_eq(44, penMmc);
|
|
assert_eq(COST_MODEL_CONSTANT, penNType);
|
|
assert_eq(4.0f, penN);
|
|
assert_eq(7, costMin.getConst());
|
|
assert_eq(DEFAULT_MIN_LINEAR_LOCAL, costMin.getCoeff());
|
|
assert_eq(8, costFloor.getConst());
|
|
assert_eq(DEFAULT_FLOOR_LINEAR_LOCAL, costFloor.getCoeff());
|
|
assert_eq(DEFAULT_N_CEIL_CONST, nCeil.getConst());
|
|
assert_eq(DEFAULT_N_CEIL_LINEAR, nCeil.getCoeff());
|
|
assert_eq(DEFAULT_N_CAT_PAIR, nCatPair);
|
|
|
|
assert_eq(2.0f, penRdExConst);
|
|
assert_eq(DEFAULT_READ_GAP_LINEAR, penRdExLinear);
|
|
assert_eq(24.0f, penRfExConst);
|
|
assert_eq(12.0f, penRfExLinear);
|
|
assert_eq(DEFAULT_SEEDMMS, multiseedMms);
|
|
assert_eq(DEFAULT_SEEDLEN, multiseedLen);
|
|
assert_eq(DEFAULT_IVAL, msIval.getType());
|
|
assert_eq(DEFAULT_IVAL_A, msIval.getCoeff());
|
|
assert_eq(DEFAULT_IVAL_B, msIval.getConst());
|
|
|
|
cout << "PASSED" << endl;
|
|
}
|
|
}
|
|
#endif /*def ALIGNER_SEED_POLICY_MAIN*/
|