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:
2024-11-07 19:01:01 +00:00
parent 3da3ddf10c
commit cde429cb80
6 changed files with 248 additions and 64 deletions

View File

@@ -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])
}