Пример #1
0
// Convert a Kmer into a string of bases
func Format(kmer Kmer, k int, alpha alphabet.Alphabet) (string, error) {
	if alpha.Len() != 4 {
		return "", ErrBadAlphabet
	}
	kmertext := make([]byte, k)

	for i := k - 1; i >= 0; i, kmer = i-1, kmer>>2 {
		kmertext[i] = byte(alpha.Letter(int(kmer & 3)))
	}

	return string(kmertext), nil
}
Пример #2
0
func makeTable(alpha alphabet.Alphabet, alnmat mat) align.SW {
	match := alnmat[0]
	mismatch := alnmat[1]
	gap := alnmat[2]
	sw := make(align.SW, alpha.Len())
	for i := range sw {
		row := make([]int, alpha.Len())
		for j := range row {
			row[j] = mismatch
		}
		row[i] = match
		sw[i] = row
	}
	for i := range sw {
		sw[0][i] = gap
		sw[i][0] = gap
	}
	return sw
}
Пример #3
0
// Match generates a penalty matrix for a.
// Perfect matches have penalty match.
// Gaps have penalty gap.
// Everything else has penalty mismatch.
// For example, Match(alphabet.DNA, 0, 1, -1) generates the original Needleman-Wunsch penalty matrix.
func Match(a alphabet.Alphabet, gap, match, mismatch int) [][]int {
	l := a.Len()
	arr := make([]int, l*l)
	g := a.IndexOf(a.Gap())
	for i := 0; i < l; i++ {
		for j := 0; j < l; j++ {
			score := mismatch
			switch {
			case i == g, j == g:
				score = gap
			case i == j:
				score = match
			}
			arr[i*l+j] = score
		}
	}
	x := make([][]int, l)
	for i := 0; i < l; i++ {
		x[i] = arr[i*l : (i+1)*l]
	}
	return x
}
Пример #4
0
func (a Fitted) alignQLetters(rSeq, qSeq alphabet.QLetters, alpha alphabet.Alphabet) ([]feat.Pair, error) {
	let := len(a)
	la := make([]int, 0, let*let)
	for _, row := range a {
		if len(row) != let {
			return nil, ErrMatrixNotSquare
		}
		la = append(la, row...)
	}

	index := alpha.LetterIndex()
	r, c := rSeq.Len()+1, qSeq.Len()+1
	table := make([]int, r*c)
	for j := range table[1:c] {
		table[j+1] = table[j] + la[index[qSeq[j].L]]
	}

	for i := 1; i < r; i++ {
		for j := 1; j < c; j++ {
			var (
				rVal = index[rSeq[i-1].L]
				qVal = index[qSeq[j-1].L]
			)
			if rVal < 0 {
				return nil, fmt.Errorf("align: illegal letter %q at position %d in rSeq", rSeq[i-1].L, i-1)
			}
			if qVal < 0 {
				return nil, fmt.Errorf("align: illegal letter %q at position %d in qSeq", qSeq[j-1].L, j-1)
			}
			p := i*c + j

			diagScore := table[p-c-1] + la[rVal*let+qVal]
			upScore := table[p-c] + la[rVal*let]
			leftScore := table[p-1] + la[qVal]

			table[p] = max3(diagScore, upScore, leftScore)
		}
	}
	if debugFitted {
		drawFittedTableQLetters(rSeq, qSeq, index, table, a)
	}

	var aln []feat.Pair
	score, last := 0, diag
	max := minInt
	var (
		i    int
		j    = c - 1
		qVal int
	)
	for {
		qVal = index[qSeq[j-1].L]
		if qVal >= 0 {
			break
		}
		j--
	}
	for y := 1; y < r; y++ {
		v := table[(y*c)+c-1]
		rVal := index[rSeq[y-1].L]
		if rVal < 0 {
			continue
		}
		if v >= max && la[rVal*let+qVal] >= 0 {
			i = y
			max = v
		}
	}
	maxI, maxJ := i, j
	for i > 0 && j > 0 {
		var (
			rVal = index[rSeq[i-1].L]
			qVal = index[qSeq[j-1].L]
		)
		switch p := i*c + j; table[p] {
		case table[p-c-1] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-c-1]
			i--
			j--
			last = diag
		case table[p-c] + la[rVal*let]:
			if last != up && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-c]
			i--
			last = up
		case table[p-1] + la[qVal]:
			if last != left && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-1]
			j--
			last = left
		default:
			panic(fmt.Sprintf("align: fitted nw internal error: no path at row: %d col:%d\n", i, j))
		}
	}

	aln = append(aln, &featPair{
		a:     feature{start: i, end: maxI},
		b:     feature{start: j, end: maxJ},
		score: score,
	})

	for i, j := 0, len(aln)-1; i < j; i, j = i+1, j-1 {
		aln[i], aln[j] = aln[j], aln[i]
	}

	return aln, nil
}
Пример #5
0
func (a SWAffine) alignLetters(rSeq, qSeq alphabet.Letters, alpha alphabet.Alphabet) ([]feat.Pair, error) {
	let := len(a.Matrix)
	if let < alpha.Len() {
		return nil, ErrMatrixWrongSize{Size: let, Len: alpha.Len()}
	}
	la := make([]int, 0, let*let)
	for _, row := range a.Matrix {
		if len(row) != let {
			return nil, ErrMatrixNotSquare
		}
		la = append(la, row...)
	}
	r, c := rSeq.Len()+1, qSeq.Len()+1
	table := make([][3]int, r*c)

	var (
		index = alpha.LetterIndex()

		maxS, maxI, maxJ = 0, 0, 0

		score  int
		scores [3]int
	)

	for i := 1; i < r; i++ {
		for j := 1; j < c; j++ {
			var (
				rVal = index[rSeq[i-1]]
				qVal = index[qSeq[j-1]]
			)
			if rVal < 0 || qVal < 0 {
				continue
			}
			p := i*c + j
			scores = [3]int{
				diag: table[p-c-1][diag],
				up:   table[p-c-1][up],
				left: table[p-c-1][left],
			}
			score = max(&scores)
			matched := score == scores[diag]
			score += la[rVal*let+qVal]
			switch {
			case score > 0:
				if score >= maxS && matched {
					maxS, maxI, maxJ = score, i, j
				}
			default:
				score = 0
			}
			table[p][diag] = score

			score = max2(
				table[p-c][diag]+a.GapOpen+la[rVal*let],
				table[p-c][up]+la[rVal*let],
			)
			if score < 0 {
				score = 0
			}
			table[p][up] = score

			score = max2(
				table[p-1][diag]+a.GapOpen+la[qVal],
				table[p-1][left]+la[qVal],
			)
			if score < 0 {
				score = 0
			}
			table[p][left] = score
		}
	}
	if debugSmithAffine {
		drawSWAffineTableLetters(rSeq, qSeq, index, table, a)
	}

	var aln []feat.Pair
	score, last, layer := 0, diag, diag
	i, j := maxI, maxJ
loop:
	for i > 0 && j > 0 {
		var (
			rVal = index[rSeq[i-1]]
			qVal = index[qSeq[j-1]]
		)
		if rVal < 0 || qVal < 0 {
			continue
		}
		switch p := i*c + j; table[p][layer] {
		case 0:
			break loop
		case table[p-c][up] + la[rVal*let]:
			if last != up && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c][up]
			i--
			layer = up
			last = up
		case table[p-1][left] + la[qVal]:
			if last != left && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-1][left]
			j--
			layer = left
			last = left
		case table[p-c][diag] + a.GapOpen + la[rVal*let]:
			if last != up && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c][diag]
			i--
			layer = diag
			last = up
		case table[p-1][diag] + a.GapOpen + la[qVal]:
			if last != left && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-1][diag]
			j--
			layer = diag
			last = left
		case table[p-c-1][diag] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c-1][diag]
			i--
			j--
			layer = diag
			last = diag
		case table[p-c-1][up] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c-1][up]
			i--
			j--
			layer = up
			last = diag
		case table[p-c-1][left] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c-1][left]
			i--
			j--
			layer = left
			last = diag

		default:
			panic(fmt.Sprintf("align: sw affine internal error: no path at row: %d col:%d layer:%s\n", i, j, "mul"[layer:layer+1]))
		}
	}

	aln = append(aln, &featPair{
		a:     feature{start: i, end: maxI},
		b:     feature{start: j, end: maxJ},
		score: score,
	})

	for i, j := 0, len(aln)-1; i < j; i, j = i+1, j-1 {
		aln[i], aln[j] = aln[j], aln[i]
	}

	return aln, nil
}
Пример #6
0
func (a SW) alignLetters(rSeq, qSeq alphabet.Letters, alpha alphabet.Alphabet) ([]feat.Pair, error) {
	let := len(a)
	la := make([]int, 0, let*let)
	for _, row := range a {
		if len(row) != let {
			return nil, ErrMatrixNotSquare
		}
		la = append(la, row...)
	}
	r, c := rSeq.Len()+1, qSeq.Len()+1
	table := make([]int, r*c)

	var (
		index = alpha.LetterIndex()

		maxS, maxI, maxJ = 0, 0, 0

		score  int
		scores [3]int
	)

	for i := 1; i < r; i++ {
		for j := 1; j < c; j++ {
			var (
				rVal = index[rSeq[i-1]]
				qVal = index[qSeq[j-1]]
			)
			if rVal < 0 || qVal < 0 {
				continue
			}
			p := i*c + j
			scores = [3]int{
				diag: table[p-c-1] + la[rVal*let+qVal],
				up:   table[p-c] + la[rVal*let],
				left: table[p-1] + la[qVal],
			}
			score = max(&scores)
			switch {
			case score > 0:
				if score >= maxS && score == scores[diag] {
					maxS, maxI, maxJ = score, i, j
				}
			default:
				score = 0
			}
			table[p] = score
		}
	}
	if debugSmith {
		drawSWTableLetters(rSeq, qSeq, index, table, a)
	}

	var aln []feat.Pair
	score, last := 0, diag
	i, j := maxI, maxJ
loop:
	for i > 0 && j > 0 {
		var (
			rVal = index[rSeq[i-1]]
			qVal = index[qSeq[j-1]]
		)
		if rVal < 0 || qVal < 0 {
			continue
		}
		switch p := i*c + j; table[p] {
		case 0:
			break loop
		case table[p-c-1] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-c-1]
			i--
			j--
			last = diag
		case table[p-c] + la[rVal*let]:
			if last != up {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-c]
			i--
			last = up
		case table[p-1] + la[qVal]:
			if last != left {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-1]
			j--
			last = left
		default:
			panic(fmt.Sprintf("align: sw internal error: no path at row: %d col:%d\n", i, j))
		}
	}

	aln = append(aln, &featPair{
		a:     feature{start: i, end: maxI},
		b:     feature{start: j, end: maxJ},
		score: score,
	})

	for i, j := 0, len(aln)-1; i < j; i, j = i+1, j-1 {
		aln[i], aln[j] = aln[j], aln[i]
	}

	return aln, nil
}
Пример #7
0
func (a SW) alignQLetters(rSeq, qSeq alphabet.QLetters, alpha alphabet.Alphabet) ([]feat.Pair, error) {
	let := len(a)
	if let < alpha.Len() {
		return nil, ErrMatrixWrongSize{Size: let, Len: alpha.Len()}
	}
	la := make([]int, 0, let*let)
	for _, row := range a {
		if len(row) != let {
			return nil, ErrMatrixNotSquare
		}
		la = append(la, row...)
	}
	r, c := rSeq.Len()+1, qSeq.Len()+1
	table := make([]int, r*c)

	var (
		index = alpha.LetterIndex()

		maxS, maxI, maxJ = 0, 0, 0

		score int
	)

	for i := 1; i < r; i++ {
		for j := 1; j < c; j++ {
			var (
				rVal = index[rSeq[i-1].L]
				qVal = index[qSeq[j-1].L]
			)
			if rVal < 0 {
				return nil, fmt.Errorf("align: illegal letter %q at position %d in rSeq", rSeq[i-1].L, i-1)
			}
			if qVal < 0 {
				return nil, fmt.Errorf("align: illegal letter %q at position %d in qSeq", qSeq[j-1].L, j-1)
			}
			p := i*c + j

			diagScore := table[p-c-1] + la[rVal*let+qVal]
			upScore := table[p-c] + la[rVal*let]
			leftScore := table[p-1] + la[qVal]

			score = max3(diagScore, upScore, leftScore)
			switch {
			case score > 0:
				if score >= maxS && score == diagScore {
					maxS, maxI, maxJ = score, i, j
				}
			default:
				score = 0
			}
			table[p] = score
		}
	}
	if debugSmith {
		drawSWTableQLetters(rSeq, qSeq, index, table, a)
	}

	var aln []feat.Pair
	score, last := 0, diag
	i, j := maxI, maxJ
loop:
	for i > 0 && j > 0 {
		var (
			rVal = index[rSeq[i-1].L]
			qVal = index[qSeq[j-1].L]
		)
		switch p := i*c + j; table[p] {
		case 0:
			break loop
		case table[p-c-1] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-c-1]
			i--
			j--
			last = diag
		case table[p-c] + la[rVal*let]:
			if last != up {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-c]
			i--
			last = up
		case table[p-1] + la[qVal]:
			if last != left {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-1]
			j--
			last = left
		default:
			panic(fmt.Sprintf("align: sw internal error: no path at row: %d col:%d\n", i, j))
		}
	}

	aln = append(aln, &featPair{
		a:     feature{start: i, end: maxI},
		b:     feature{start: j, end: maxJ},
		score: score,
	})

	for i, j := 0, len(aln)-1; i < j; i, j = i+1, j-1 {
		aln[i], aln[j] = aln[j], aln[i]
	}

	return aln, nil
}
Пример #8
0
func (a NWAffine) alignLetters(rSeq, qSeq alphabet.Letters, alpha alphabet.Alphabet) ([]feat.Pair, error) {
	let := len(a.Matrix)
	la := make([]int, 0, let*let)
	for _, row := range a.Matrix {
		if len(row) != let {
			return nil, ErrMatrixNotSquare
		}
		la = append(la, row...)
	}

	index := alpha.LetterIndex()
	r, c := rSeq.Len()+1, qSeq.Len()+1
	table := make([][3]int, r*c)
	table[0] = [3]int{
		diag: 0,
		up:   minInt,
		left: minInt,
	}
	table[1] = [3]int{
		diag: minInt,
		up:   minInt,
		left: a.GapOpen + la[index[qSeq[0]]],
	}
	for j := range table[2:c] {
		table[j+2] = [3]int{
			diag: minInt,
			up:   minInt,
			left: table[j+1][left] + la[index[qSeq[j+1]]],
		}
	}
	table[c] = [3]int{
		diag: minInt,
		up:   a.GapOpen + la[index[rSeq[0]]*let],
		left: minInt,
	}
	for i := 2; i < r; i++ {
		table[i*c] = [3]int{
			diag: minInt,
			up:   table[(i-1)*c][up] + la[index[rSeq[i-1]]*let],
			left: minInt,
		}
	}

	var scores [3]int
	for i := 1; i < r; i++ {
		for j := 1; j < c; j++ {
			var (
				rVal = index[rSeq[i-1]]
				qVal = index[qSeq[j-1]]
			)
			if rVal < 0 || qVal < 0 {
				continue
			}
			p := i*c + j
			scores = [3]int{
				diag: table[p-c-1][diag],
				up:   table[p-c-1][up],
				left: table[p-c-1][left],
			}
			table[p][diag] = max(&scores) + la[rVal*let+qVal]

			table[p][up] = max2(
				add(table[p-c][diag], a.GapOpen+la[rVal*let]),
				add(table[p-c][up], la[rVal*let]),
			)

			table[p][left] = max2(
				add(table[p-1][diag], a.GapOpen+la[qVal]),
				add(table[p-1][left], la[qVal]),
			)
		}
	}
	if debugNeedleAffine {
		drawNWAffineTableLetters(rSeq, qSeq, index, table, a)
	}

	var (
		aln   []feat.Pair
		layer int
	)
	score, last := 0, diag
	i, j := r-1, c-1
	t := table[i*c+j]
	best := t[0]
	for i, s := range t[1:] {
		if s > best {
			best, layer = s, i+1
		}
	}
	maxI, maxJ := i, j
	for i > 0 && j > 0 {
		var (
			rVal = index[rSeq[i-1]]
			qVal = index[qSeq[j-1]]
		)
		if rVal < 0 || qVal < 0 {
			continue
		}
		switch p := i*c + j; table[p][layer] {
		case table[p-c][up] + la[rVal*let]:
			if last != up && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c][up]
			i--
			layer = up
			last = up
		case table[p-1][left] + la[qVal]:
			if last != left && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-1][left]
			j--
			layer = left
			last = left
		case table[p-c][diag] + a.GapOpen + la[rVal*let]:
			if last != up && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c][diag]
			i--
			layer = diag
			last = up
		case table[p-1][diag] + a.GapOpen + la[qVal]:
			if last != left && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-1][diag]
			j--
			layer = diag
			last = left
		case table[p-c-1][up] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c-1][up]
			i--
			j--
			layer = up
			last = diag
		case table[p-c-1][left] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c-1][left]
			i--
			j--
			layer = left
			last = diag
		case table[p-c-1][diag] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c-1][diag]
			i--
			j--
			layer = diag
			last = diag

		default:
			panic(fmt.Sprintf("align: nw affine internal error: no path at row: %d col:%d layer:%s\n", i, j, "mul"[layer:layer+1]))
		}
	}

	aln = append(aln, &featPair{
		a:     feature{start: i, end: maxI},
		b:     feature{start: j, end: maxJ},
		score: score,
	})
	if i != j {
		aln = append(aln, &featPair{
			a:     feature{start: 0, end: i},
			b:     feature{start: 0, end: j},
			score: table[i*c+j][last],
		})
	}

	for i, j := 0, len(aln)-1; i < j; i, j = i+1, j-1 {
		aln[i], aln[j] = aln[j], aln[i]
	}

	return aln, nil
}
Пример #9
0
func (a FittedAffine) alignLetters(rSeq, qSeq alphabet.Letters, alpha alphabet.Alphabet) ([]feat.Pair, error) {
	let := len(a.Matrix)
	la := make([]int, 0, let*let)
	for _, row := range a.Matrix {
		if len(row) != let {
			return nil, ErrMatrixNotSquare
		}
		la = append(la, row...)
	}

	index := alpha.LetterIndex()
	r, c := rSeq.Len()+1, qSeq.Len()+1
	table := make([][3]int, r*c)
	table[0] = [3]int{
		diag: 0,
		up:   minInt,
		left: minInt,
	}
	table[1] = [3]int{
		diag: minInt,
		up:   minInt,
	}
	table[1][left] = a.GapOpen + la[index[qSeq[0]]]
	for j := range table[2:c] {
		table[j+2] = [3]int{
			diag: minInt,
			up:   minInt,
			left: table[j+1][left] + la[index[qSeq[j+1]]],
		}
	}
	table[c] = [3]int{
		diag: minInt,
		left: minInt,
	}
	for i := 2; i < r; i++ {
		table[i*c] = [3]int{
			diag: minInt,
			left: minInt,
		}
	}

	for i := 1; i < r; i++ {
		for j := 1; j < c; j++ {
			var (
				rVal = index[rSeq[i-1]]
				qVal = index[qSeq[j-1]]
			)
			if rVal < 0 {
				return nil, fmt.Errorf("align: illegal letter %q at position %d in rSeq", rSeq[i-1], i-1)
			}
			if qVal < 0 {
				return nil, fmt.Errorf("align: illegal letter %q at position %d in qSeq", qSeq[j-1], j-1)
			}
			p := i*c + j

			diagScore := table[p-c-1][diag]
			upScore := table[p-c-1][up]
			leftScore := table[p-c-1][left]

			table[p][diag] = max3(diagScore, upScore, leftScore) + la[rVal*let+qVal]

			table[p][up] = max2(
				add(table[p-c][diag], a.GapOpen+la[rVal*let]),
				add(table[p-c][up], la[rVal*let]),
			)

			table[p][left] = max2(
				add(table[p-1][diag], a.GapOpen+la[qVal]),
				add(table[p-1][left], la[qVal]),
			)
		}
	}
	if debugFittedAffine {
		drawFittedAffineTableLetters(rSeq, qSeq, index, table, a)
	}

	var aln []feat.Pair
	score, last, layer := 0, diag, diag
	var (
		i int
		j = c - 1
	)
	max := minInt
	for y := 1; y < r; y++ {
		v := table[(y*c)+c-1][diag]
		if v >= max {
			i = y
			max = v
		}
	}
	maxI, maxJ := i, j
	for i > 0 && j > 0 {
		var (
			rVal = index[rSeq[i-1]]
			qVal = index[qSeq[j-1]]
		)
		switch p := i*c + j; table[p][layer] {
		case table[p-c][up] + la[rVal*let]:
			if last != up && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c][up]
			i--
			layer = up
			last = up
		case table[p-1][left] + la[qVal]:
			if last != left && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-1][left]
			j--
			layer = left
			last = left
		case table[p-c][diag] + a.GapOpen + la[rVal*let]:
			if last != up && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c][diag]
			i--
			layer = diag
			last = up
		case table[p-1][diag] + a.GapOpen + la[qVal]:
			if last != left && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-1][diag]
			j--
			layer = diag
			last = left
		case table[p-c-1][up] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c-1][up]
			i--
			j--
			layer = up
			last = diag
		case table[p-c-1][left] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c-1][left]
			i--
			j--
			layer = left
			last = diag
		case table[p-c-1][diag] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p][layer] - table[p-c-1][diag]
			i--
			j--
			layer = diag
			last = diag

		default:
			panic(fmt.Sprintf("align: fitted nw affine internal error: no path at row: %d col:%d layer:%s\n", i, j, "mul"[layer:layer+1]))
		}
	}

	aln = append(aln, &featPair{
		a:     feature{start: i, end: maxI},
		b:     feature{start: j, end: maxJ},
		score: score,
	})

	for i, j := 0, len(aln)-1; i < j; i, j = i+1, j-1 {
		aln[i], aln[j] = aln[j], aln[i]
	}

	return aln, nil
}
Пример #10
0
func (a NW) alignLetters(rSeq, qSeq alphabet.Letters, alpha alphabet.Alphabet) ([]feat.Pair, error) {
	let := len(a)
	if let < alpha.Len() {
		return nil, ErrMatrixWrongSize{Size: let, Len: alpha.Len()}
	}
	la := make([]int, 0, let*let)
	for _, row := range a {
		if len(row) != let {
			return nil, ErrMatrixNotSquare
		}
		la = append(la, row...)
	}

	index := alpha.LetterIndex()
	r, c := rSeq.Len()+1, qSeq.Len()+1
	table := make([]int, r*c)
	for j := range table[1:c] {
		table[j+1] = table[j] + la[index[qSeq[j]]]
	}
	for i := 1; i < r; i++ {
		table[i*c] = table[(i-1)*c] + la[index[rSeq[i-1]]*let]
	}

	var scores [3]int
	for i := 1; i < r; i++ {
		for j := 1; j < c; j++ {
			var (
				rVal = index[rSeq[i-1]]
				qVal = index[qSeq[j-1]]
			)
			if rVal < 0 || qVal < 0 {
				continue
			}
			p := i*c + j
			scores = [3]int{
				diag: table[p-c-1] + la[rVal*let+qVal],
				up:   table[p-c] + la[rVal*let],
				left: table[p-1] + la[qVal],
			}
			table[p] = max(&scores)
		}
	}
	if debugNeedle {
		drawNWTableLetters(rSeq, qSeq, index, table, a)
	}

	var aln []feat.Pair
	score, last := 0, diag
	i, j := r-1, c-1
	maxI, maxJ := i, j
	for i > 0 && j > 0 {
		var (
			rVal = index[rSeq[i-1]]
			qVal = index[qSeq[j-1]]
		)
		if rVal < 0 || qVal < 0 {
			continue
		}
		switch p := i*c + j; table[p] {
		case table[p-c-1] + la[rVal*let+qVal]:
			if last != diag {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-c-1]
			i--
			j--
			last = diag
		case table[p-c] + la[rVal*let]:
			if last != up && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-c]
			i--
			last = up
		case table[p-1] + la[qVal]:
			if last != left && p != len(table)-1 {
				aln = append(aln, &featPair{
					a:     feature{start: i, end: maxI},
					b:     feature{start: j, end: maxJ},
					score: score,
				})
				maxI, maxJ = i, j
				score = 0
			}
			score += table[p] - table[p-1]
			j--
			last = left
		default:
			panic(fmt.Sprintf("align: nw internal error: no path at row: %d col:%d\n", i, j))
		}
	}

	aln = append(aln, &featPair{
		a:     feature{start: i, end: maxI},
		b:     feature{start: j, end: maxJ},
		score: score,
	})
	if i != j {
		aln = append(aln, &featPair{
			a:     feature{start: 0, end: i},
			b:     feature{start: 0, end: j},
			score: table[i*c+j],
		})
	}

	for i, j := 0, len(aln)-1; i < j; i, j = i+1, j-1 {
		aln[i], aln[j] = aln[j], aln[i]
	}

	return aln, nil
}
Пример #11
0
func genCode(w io.Writer, m string, a alphabet.Alphabet) error {
	f, err := os.Open(m)
	if err != nil {
		return err
	}
	b, err := ioutil.ReadAll(f)
	if err != nil {
		return err
	}
	s := string(b)
	var (
		ind       = a.LetterIndex()
		ref       []string
		perm      []int
		mat       [][]int
		row       int
		lastBlank bool
	)
	for _, l := range strings.Split(s, "\n") {
		nsl := noSpace(l)
		switch {
		case len(l) == 0:
			if !lastBlank {
				lastBlank = true
				fmt.Fprintln(w, "\t//")
			}
		case l[0] == ' ':
			ref = strings.Fields(nsl)
			perm = make([]int, a.Len())
			for i, l := range ref {
				li := ind[l[0]]
				if li < 0 {
					continue
				}
				perm[li] = i
			}
			mat = make([][]int, a.Len())
			for j := range mat {
				mat[j] = make([]int, a.Len())
			}
			fallthrough
		case l[0] == '#':
			lastBlank = false
			fmt.Fprintf(w, "\t// %s\n", l)
		default:
			lastBlank = false
			fmt.Fprintf(w, "\t// %s\n", l)
			for col, f := range strings.Fields(nsl)[1:] {
				mat[ind[ref[row][0]]][ind[ref[col][0]]], err = strconv.Atoi(f)
				if err != nil {
					return err
				}
			}
			row++
		}
	}
	fmt.Fprintf(w, "\t%s = [][]int{\n\t\t/*       ", strings.Replace(m, ".", "_", -1))
	for j := range mat {
		fmt.Printf("%c ", toUpper(a.Letter(j)))
	}
	fmt.Fprintln(w, "*/")
	for i := range mat {
		fmt.Printf("\t\t/* %c */ {", toUpper(a.Letter(i)))
		for j, e := range mat[i] {
			fmt.Fprint(w, e)
			if j < len(mat[i])-1 {
				fmt.Print(", ")
			}
		}
		fmt.Fprintln(w, "},")
	}
	fmt.Fprintln(w, "\t}")
	return nil
}