fix issue in WFBacktrace and change format to proper CIGAR,
add test to ensure CIGAR correctness in the case of different traceback results, add DecodeCIGAR function to exports
This commit is contained in:
69
pkg/utils.go
69
pkg/utils.go
@@ -2,11 +2,55 @@ package wfa
|
||||
|
||||
import (
|
||||
"math"
|
||||
"unicode/utf8"
|
||||
"strings"
|
||||
|
||||
"golang.org/x/exp/constraints"
|
||||
)
|
||||
|
||||
func UIntToString(num uint) string { // num assumed to be positive
|
||||
var builder strings.Builder
|
||||
|
||||
for num > 0 {
|
||||
digit := num % 10
|
||||
builder.WriteRune(rune('0' + digit))
|
||||
num /= 10
|
||||
}
|
||||
|
||||
// Reverse the string as we built it in reverse order
|
||||
str := []rune(builder.String())
|
||||
for i, j := 0, len(str)-1; i < j; i, j = i+1, j-1 {
|
||||
str[i], str[j] = str[j], str[i]
|
||||
}
|
||||
|
||||
return string(str)
|
||||
}
|
||||
|
||||
func RunLengthDecode(encoded string) string {
|
||||
decoded := strings.Builder{}
|
||||
length := len(encoded)
|
||||
i := 0
|
||||
|
||||
for i < length {
|
||||
// If the current character is a digit, we need to extract the run length
|
||||
runLength := 0
|
||||
for i < length && encoded[i] >= '0' && encoded[i] <= '9' {
|
||||
runLength = runLength*10 + int(encoded[i]-'0')
|
||||
i++
|
||||
}
|
||||
|
||||
// The next character will be the character to repeat
|
||||
if i < length {
|
||||
char := encoded[i]
|
||||
for j := 0; j < runLength; j++ {
|
||||
decoded.WriteByte(char)
|
||||
}
|
||||
i++ // Move past the character
|
||||
}
|
||||
}
|
||||
|
||||
return decoded.String()
|
||||
}
|
||||
|
||||
func SafeMin[T constraints.Integer](values []T, idx int) T {
|
||||
return values[idx]
|
||||
}
|
||||
@@ -51,21 +95,6 @@ func SafeArgMin[T constraints.Integer](valids []bool, values []T) (bool, int) {
|
||||
}
|
||||
}
|
||||
|
||||
func Reverse(s string) string {
|
||||
size := len(s)
|
||||
buf := make([]byte, size)
|
||||
for start := 0; start < size; {
|
||||
r, n := utf8.DecodeRuneInString(s[start:])
|
||||
start += n
|
||||
utf8.EncodeRune(buf[size-start:], r)
|
||||
}
|
||||
return string(buf)
|
||||
}
|
||||
|
||||
func Splice(s string, c rune, idx int) string {
|
||||
return s[:idx] + string(c) + s[idx:]
|
||||
}
|
||||
|
||||
func NextLoHi(M WavefrontComponent, I WavefrontComponent, D WavefrontComponent, score int, penalties Penalty) (int, int) {
|
||||
x := penalties.X
|
||||
o := penalties.O
|
||||
@@ -117,11 +146,8 @@ func NextD(M WavefrontComponent, D WavefrontComponent, score int, k int, penalti
|
||||
a_ok, a, _ := M.GetVal(score-o-e, k+1)
|
||||
b_ok, b, _ := D.GetVal(score-e, k+1)
|
||||
|
||||
ok, nextDTraceback := SafeArgMax(
|
||||
[]bool{a_ok, b_ok},
|
||||
[]uint32{a, b},
|
||||
)
|
||||
nextDVal := SafeMax([]uint32{a, b}, nextDTraceback) // nothing special
|
||||
ok, nextDTraceback := SafeArgMax([]bool{a_ok, b_ok}, []uint32{a, b})
|
||||
nextDVal := SafeMax([]uint32{a, b}, nextDTraceback)
|
||||
if ok {
|
||||
D.SetVal(score, k, nextDVal, []Traceback{OpenDel, ExtdDel}[nextDTraceback])
|
||||
}
|
||||
@@ -137,7 +163,6 @@ func NextM(M WavefrontComponent, I WavefrontComponent, D WavefrontComponent, sco
|
||||
|
||||
ok, nextMTraceback := SafeArgMax([]bool{a_ok, b_ok, c_ok}, []uint32{a, b, c})
|
||||
nextMVal := SafeMax([]uint32{a, b, c}, nextMTraceback)
|
||||
|
||||
if ok {
|
||||
M.SetVal(score, k, nextMVal, []Traceback{Sub, Ins, Del}[nextMTraceback])
|
||||
}
|
||||
|
Reference in New Issue
Block a user