Files
obitools4/pkg/obialign/is_d0_or_d1.go
Eric Coissac 9e63013bc2 Correction on obiformat of bug leading to partial parsing and add godocs
Former-commit-id: b27105355f1a330eedf6eaa72c8ac94f06806c28
2024-05-07 10:54:12 +02:00

97 lines
1.8 KiB
Go

package obialign
import (
"git.metabarcoding.org/obitools/obitools4/obitools4/pkg/obiseq"
"golang.org/x/exp/constraints"
)
// abs computes the absolute value of a given float or integer.
//
// x: the input value of type k (float or integer).
// k: the return type, which is the absolute value of x.
func abs[k constraints.Float | constraints.Integer](x k) k {
if x < 0 {
return -x
}
return x
}
// D1Or0 checks if two sequences are identical or differ by one position.
//
// Parameters:
// - seq1: a pointer to the first sequence
// - seq2: a pointer to the second sequence
//
// Returns:
// - int: 0 if the sequences are identical or 0 if they differ by one position, -1 otherwise
// - int: the position where the sequences differ, -1 if they are identical
// - byte: the character in the first sequence at the differing position, '-' if it's a deletion
// - byte: the character in the second sequence at the differing position, '-' if it's a deletion
func D1Or0(seq1, seq2 *obiseq.BioSequence) (int, int, byte, byte) {
pos := -1
l1 := seq1.Len()
l2 := seq2.Len()
if abs(l1-l2) > 1 {
return -1, pos, 0, 0
}
s1 := seq1.Sequence()
s2 := seq2.Sequence()
b1 := 0
b2 := 0
// Scans the sequences from their beginings as long as they are identical
for b1 < l1 && b2 < l2 && s1[b1] == s2[b2] {
b1++
b2++
}
if b1 == l1 && b2 == l2 {
return 0, pos, 0, 0
}
// Scans the sequences from their ends as long as they are identical
e1 := l1 - 1
e2 := l2 - 1
for (e1 > b1 || e2 > b2) && s1[e1] == s2[e2] {
e1--
e2--
}
if (l1 == l2 && (e1 > b1 || e2 > b2)) ||
(l1 > l2 && e1 > b1) ||
(l1 < l2 && e2 > b2) {
return -1, pos, 0, 0
}
if b1 >= e1 {
if e1 > e2 {
pos = e1
} else {
pos = e2
}
}
a1 := byte('-')
a2 := byte('-')
if e2 >= e1 {
a2 = s2[e2]
}
if e2 <= e1 {
a1 = s1[e1]
}
return 1, pos, a1, a2
}