mirror of
https://github.com/metabarcoding/obitools4.git
synced 2025-06-29 16:20:46 +00:00
97 lines
1.8 KiB
Go
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
|
|
|
|
}
|