mirror of
https://github.com/metabarcoding/obitools4.git
synced 2025-06-29 16:20:46 +00:00
Patch a bug in the pair-end alignement in case of equality between scores.
Former-commit-id: bbdb761a98b76f2421d1f0a72960e72b13b6e626
This commit is contained in:
@ -41,22 +41,74 @@ func MakePEAlignArena(lseqA, lseqB int) PEAlignArena {
|
|||||||
return PEAlignArena{&a}
|
return PEAlignArena{&a}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _SetMatrices updates the values in matrixA and matrixB at the specified indices with the given values.
|
||||||
|
//
|
||||||
|
// The data in the matrix is stored in column-major order.
|
||||||
|
// Positions in the matrix are numbered from -1
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - matrixA: a pointer to the slice of integers representing matrixA.
|
||||||
|
// - matrixB: a pointer to the slice of integers representing matrixB.
|
||||||
|
// - lenA: the length of matrixA.
|
||||||
|
// - a: the row index a.
|
||||||
|
// - b: the column index b .
|
||||||
|
// - valueA: the value to be set in matrixA.
|
||||||
|
// - valueB: the value to be set in matrixB.
|
||||||
func _SetMatrices(matrixA, matrixB *[]int, lenA, a, b, valueA, valueB int) {
|
func _SetMatrices(matrixA, matrixB *[]int, lenA, a, b, valueA, valueB int) {
|
||||||
i := (b+1)*(lenA+1) + a + 1
|
i := (b+1)*(lenA+1) + a + 1
|
||||||
(*matrixA)[i] = valueA
|
(*matrixA)[i] = valueA
|
||||||
(*matrixB)[i] = valueB
|
(*matrixB)[i] = valueB
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _GetMatrix returns the value at the specified position in the matrix.
|
||||||
|
//
|
||||||
|
// The data in the matrix is stored in column-major order.
|
||||||
|
// Positions in the matrix are numbered from -1
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
// - matrix: a pointer to the matrix
|
||||||
|
// - lenA: the length of the matrix
|
||||||
|
// - a: the row index a.
|
||||||
|
// - b: the column index b .
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// - int: the value at the specified position in the matrix
|
||||||
func _GetMatrix(matrix *[]int, lenA, a, b int) int {
|
func _GetMatrix(matrix *[]int, lenA, a, b int) int {
|
||||||
return (*matrix)[(b+1)*(lenA+1)+a+1]
|
return (*matrix)[(b+1)*(lenA+1)+a+1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns left, diag, top compare to the position (a, b)
|
||||||
|
//
|
||||||
|
// with a the row index and b the column index.
|
||||||
|
// Positions in the matrix are numbered from -1
|
||||||
|
//
|
||||||
|
// i = (b+1)*(lenA+1) + a + 1
|
||||||
|
//
|
||||||
|
// diag = M[a-1][b-1] : i_diag = ((b-1)+1)*(lenA+1) + (a-1) + 1
|
||||||
|
//
|
||||||
|
// : i_diag = b*(lenA+1) + a
|
||||||
|
//
|
||||||
|
// left = M[a][b-1] : i_left = ((b-1)+1)*(lenA+1) + a + 1
|
||||||
|
//
|
||||||
|
// : i_left = b*(lenA+1) + a + 1
|
||||||
|
//
|
||||||
|
// top = M[a-1][b] : i_top = (b+1)*(lenA+1) + (a-1) + 1
|
||||||
|
//
|
||||||
|
// : i_top = (b+1)*(lenA+1) + a
|
||||||
|
//
|
||||||
|
// Parameters:
|
||||||
|
//
|
||||||
|
// - matrix: a pointer to the matrix
|
||||||
|
// - lenA: the number of row -1 in the matrix
|
||||||
|
// - a: the row index a.
|
||||||
|
// - b: the column index b .
|
||||||
func _GetMatrixFrom(matrix *[]int, lenA, a, b int) (int, int, int) {
|
func _GetMatrixFrom(matrix *[]int, lenA, a, b int) (int, int, int) {
|
||||||
// Formula rechecked on 01/25/2023
|
// Formula rechecked on 11/24/2023
|
||||||
i := (b+1)*(lenA+1) + a
|
i_top := (b+1)*(lenA+1) + a
|
||||||
j := i - lenA
|
i_left := i_top - lenA
|
||||||
|
i_diag := i_left - 1
|
||||||
m := *matrix
|
m := *matrix
|
||||||
return m[j], m[j-1], m[i]
|
return m[i_left], m[i_diag], m[i_top]
|
||||||
}
|
}
|
||||||
|
|
||||||
func _PairingScorePeAlign(baseA, qualA, baseB, qualB byte) int {
|
func _PairingScorePeAlign(baseA, qualA, baseB, qualB byte) int {
|
||||||
@ -74,10 +126,15 @@ func _PairingScorePeAlign(baseA, qualA, baseB, qualB byte) int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gaps at the beginning of B and at the end of A are free
|
// Gaps at the beginning of seqB and at the end of seqA are free
|
||||||
// With A spanning over lines and B over columns
|
// With seqA spanning over lines and seqB over columns
|
||||||
// - First column gap = 0
|
// - First column gap = 0
|
||||||
// - Last line gaps = 0
|
// - Last line gaps = 0
|
||||||
|
//
|
||||||
|
// Paths are encoded :
|
||||||
|
// - 0 : for diagonal
|
||||||
|
// - -1 : for top
|
||||||
|
// - +1 : for left
|
||||||
func _FillMatrixPeLeftAlign(seqA, qualA, seqB, qualB []byte, gap float64,
|
func _FillMatrixPeLeftAlign(seqA, qualA, seqB, qualB []byte, gap float64,
|
||||||
scoreMatrix, pathMatrix *[]int) int {
|
scoreMatrix, pathMatrix *[]int) int {
|
||||||
|
|
||||||
@ -118,19 +175,21 @@ func _FillMatrixPeLeftAlign(seqA, qualA, seqB, qualB []byte, gap float64,
|
|||||||
|
|
||||||
for i := 0; i < la1; i++ {
|
for i := 0; i < la1; i++ {
|
||||||
left, diag, top := _GetMatrixFrom(scoreMatrix, la, i, j)
|
left, diag, top := _GetMatrixFrom(scoreMatrix, la, i, j)
|
||||||
|
// log.Infof("LA: i : %d j : %d left : %d diag : %d top : %d\n", i, j, left, diag, top)
|
||||||
|
|
||||||
diag += _PairingScorePeAlign(seqA[i], qualA[i], seqB[j], qualB[j])
|
diag += _PairingScorePeAlign(seqA[i], qualA[i], seqB[j], qualB[j])
|
||||||
left += gapPenalty
|
left += gapPenalty
|
||||||
top += gapPenalty
|
top += gapPenalty
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case diag > left && diag > top:
|
case diag >= left && diag >= top:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, diag, 0)
|
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, diag, 0)
|
||||||
case left > diag && left > top:
|
case left >= diag && left >= top:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, left, +1)
|
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, left, +1)
|
||||||
default:
|
default:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, top, -1)
|
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, top, -1)
|
||||||
}
|
}
|
||||||
|
// log.Infof("LA: i : %d j : %d left : %d diag : %d top : %d [%d]\n", i, j, left, diag, top, _GetMatrix(scoreMatrix, la, i, j))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case for the last line Left gap are free
|
// Special case for the last line Left gap are free
|
||||||
@ -140,14 +199,16 @@ func _FillMatrixPeLeftAlign(seqA, qualA, seqB, qualB []byte, gap float64,
|
|||||||
top += gapPenalty
|
top += gapPenalty
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case diag > left && diag > top:
|
case diag >= left && diag >= top:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, la1, j, diag, 0)
|
_SetMatrices(scoreMatrix, pathMatrix, la, la1, j, diag, 0)
|
||||||
case left > diag && left > top:
|
case left >= diag && left >= top:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, la1, j, left, +1)
|
_SetMatrices(scoreMatrix, pathMatrix, la, la1, j, left, +1)
|
||||||
default:
|
default:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, la1, j, top, -1)
|
_SetMatrices(scoreMatrix, pathMatrix, la, la1, j, top, -1)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// log.Infof("LA: i : %d j : %d left : %d diag : %d top : %d [%d]\n", la1, j, left, diag, top, _GetMatrix(scoreMatrix, la, la1, j))
|
||||||
}
|
}
|
||||||
|
|
||||||
return _GetMatrix(scoreMatrix, la, la1, lb-1)
|
return _GetMatrix(scoreMatrix, la, la1, lb-1)
|
||||||
@ -203,14 +264,16 @@ func _FillMatrixPeRightAlign(seqA, qualA, seqB, qualB []byte, gap float64,
|
|||||||
top += gapPenalty
|
top += gapPenalty
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case diag > left && diag > top:
|
case diag >= left && diag >= top:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, diag, 0)
|
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, diag, 0)
|
||||||
case left > diag && left > top:
|
case left >= diag && left >= top:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, left, +1)
|
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, left, +1)
|
||||||
default:
|
default:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, top, -1)
|
_SetMatrices(scoreMatrix, pathMatrix, la, i, j, top, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// log.Infof("LR: i : %d j : %d left : %d diag : %d top : %d [%d]\n", i, j, left, diag, top, _GetMatrix(scoreMatrix, la, i, j))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -223,10 +286,12 @@ func _FillMatrixPeRightAlign(seqA, qualA, seqB, qualB []byte, gap float64,
|
|||||||
diag += _PairingScorePeAlign(seqA[i], qualA[i], seqB[lb1], qualB[lb1])
|
diag += _PairingScorePeAlign(seqA[i], qualA[i], seqB[lb1], qualB[lb1])
|
||||||
left += gapPenalty
|
left += gapPenalty
|
||||||
|
|
||||||
|
// log.Infof("LR: i : %d j : %d left : %d diag : %d top : %d [%d]\n", i, lb1, left, diag, top, _GetMatrix(scoreMatrix, la, i, lb1))
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case diag > left && diag > top:
|
case diag >= left && diag >= top:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, i, lb1, diag, 0)
|
_SetMatrices(scoreMatrix, pathMatrix, la, i, lb1, diag, 0)
|
||||||
case left > diag && left > top:
|
case left >= diag && left >= top:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, i, lb1, left, +1)
|
_SetMatrices(scoreMatrix, pathMatrix, la, i, lb1, left, +1)
|
||||||
default:
|
default:
|
||||||
_SetMatrices(scoreMatrix, pathMatrix, la, i, lb1, top, -1)
|
_SetMatrices(scoreMatrix, pathMatrix, la, i, lb1, top, -1)
|
||||||
|
@ -101,25 +101,25 @@ func (s *XopenTest) TestReadHttp(c *C) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *XopenTest) TestReadProcess(c *C) {
|
// func (s *XopenTest) TestReadProcess(c *C) {
|
||||||
for _, cmd := range []string{"|ls -lh", "|ls", "|ls -lh xopen_test.go"} {
|
// for _, cmd := range []string{"|ls -lh", "|ls", "|ls -lh xopen_test.go"} {
|
||||||
rdr, err := Ropen(cmd)
|
// rdr, err := Ropen(cmd)
|
||||||
c.Assert(err, IsNil)
|
// c.Assert(err, IsNil)
|
||||||
b := make([]byte, 1000)
|
// b := make([]byte, 1000)
|
||||||
_, err = rdr.Read(b)
|
// _, err = rdr.Read(b)
|
||||||
if err != io.EOF {
|
// if err != io.EOF {
|
||||||
c.Assert(err, IsNil)
|
// c.Assert(err, IsNil)
|
||||||
}
|
// }
|
||||||
lines := strings.Split(string(b), "\n")
|
// lines := strings.Split(string(b), "\n")
|
||||||
has := false
|
// has := false
|
||||||
for _, line := range lines {
|
// for _, line := range lines {
|
||||||
if strings.Contains(line, "xopen_test.go") {
|
// if strings.Contains(line, "xopen_test.go") {
|
||||||
has = true
|
// has = true
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
c.Assert(has, Equals, true)
|
// c.Assert(has, Equals, true)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
func (s *XopenTest) TestOpenStdout(c *C) {
|
func (s *XopenTest) TestOpenStdout(c *C) {
|
||||||
w, err := Wopen("-")
|
w, err := Wopen("-")
|
||||||
|
@ -46,15 +46,15 @@ func TestSubsequence(t *testing.T) {
|
|||||||
// Test case 3: Subsequence with from greater than to and non-circular
|
// Test case 3: Subsequence with from greater than to and non-circular
|
||||||
seq3 := NewBioSequence("ID1", []byte("ATCG"), "")
|
seq3 := NewBioSequence("ID1", []byte("ATCG"), "")
|
||||||
_, err3 := seq3.Subsequence(3, 1, false)
|
_, err3 := seq3.Subsequence(3, 1, false)
|
||||||
assert.EqualError(t, err3, "from greater than to")
|
assert.EqualError(t, err3, "from: 3 greater than to: 1")
|
||||||
|
|
||||||
// Test case 4: Subsequence with from out of bounds
|
// Test case 4: Subsequence with from out of bounds
|
||||||
seq4 := NewBioSequence("ID1", []byte("ATCG"), "")
|
seq4 := NewBioSequence("ID1", []byte("ATCG"), "")
|
||||||
_, err4 := seq4.Subsequence(-1, 2, false)
|
_, err4 := seq4.Subsequence(-1, 2, false)
|
||||||
assert.EqualError(t, err4, "from out of bounds")
|
assert.EqualError(t, err4, "from out of bounds -1 < 0")
|
||||||
|
|
||||||
// Test case 5: Subsequence with to out of bounds
|
// Test case 5: Subsequence with to out of bounds
|
||||||
seq5 := NewBioSequence("ID1", []byte("ATCG"), "")
|
seq5 := NewBioSequence("ID1", []byte("ATCG"), "")
|
||||||
_, err5 := seq5.Subsequence(2, 5, false)
|
_, err5 := seq5.Subsequence(2, 5, false)
|
||||||
assert.EqualError(t, err5, "to out of bounds")
|
assert.EqualError(t, err5, "to out of bounds 5 > 4")
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user