package obialign // import ( // "git.metabarcoding.org/lecasofts/go/obitools/pkg/obiutils" // "git.metabarcoding.org/lecasofts/go/obitools/pkg/obiseq" // ) const wsize = 16 const dwsize = wsize * 2 // Out values are always the smallest // Among in values, they rank according to their score // For equal score the shortest path is the best func encodeValues(score, length int, out bool) uint64 { const mask = uint64(1<> wsize) & mask) length := int(((value + 1) ^ mask) & mask) out := (value & outmask) == 0 return score, length, out } func _incpath(value uint64) uint64 { return value - 1 } func _incscore(value uint64) uint64 { const incr = uint64(1) << wsize return value + incr } func _setout(value uint64) uint64 { const outmask = ^(uint64(1) << dwsize) return value & outmask } var _empty = encodeValues(0, 0, false) var _out = encodeValues(0, 30000, true) var _notavail = encodeValues(0, 30000, false) // func FastLCSScore(seqA, seqB *obiseq.BioSequence, maxError int, buffer *[]uint64) (int, int) { // lA := seqA.Len() // lB := seqB.Len() // // Ensure that A is the longest // if lA < lB { // seqA, seqB = seqB, seqA // lA, lB = lB, lA // } // if maxError == -1 { // maxError = lA * 2 // } // delta := lA - lB // // The difference of length is larger the maximum allowed errors // if delta > maxError { // return -1, -1 // } // // Doit-on vraiment diviser par deux ??? pas certain // extra := (maxError - delta) + 1 // even := 1 + delta + 2*extra // width := 2*even - 1 // if buffer == nil { // var local []uint64 // buffer = &local // } // if cap(*buffer) < 2*width { // *buffer = make([]uint64, 3*width) // } // previous := (*buffer)[0:width] // current := (*buffer)[width:(2 * width)] // previous[extra] = _empty // previous[extra+even] = encodeValues(0, 1, false) // previous[extra+even-1] = encodeValues(0, 1, false) // N := lB + ((delta) >> 1) // bA := seqA.Sequence() // bB := seqB.Sequence() // // log.Println("N = ", N) // for y := 1; y <= N; y++ { // // in_matrix := false // x1 := y - lB + extra // x2 := extra - y // xs := obiutils.MaxInt(obiutils.MaxInt(x1, x2), 0) // x1 = y + extra // x2 = lA + extra - y // xf := obiutils.MinInt(obiutils.MinInt(x1, x2), even-1) + 1 // for x := xs; x < xf; x++ { // i := y - x + extra // j := y + x - extra // var Sdiag, Sleft, Sup uint64 // switch { // case i == 0: // Sup = _notavail // Sdiag = _notavail // Sleft = encodeValues(0, j-1, false) // case j == 0: // Sup = encodeValues(0, i-1, false) // Sdiag = _notavail // Sleft = _notavail // default: // Sdiag = previous[x] // if bA[j-1] == bB[i-1] { // Sdiag = _incscore(Sdiag) // } // if x < (even - 1) { // Sup = previous[x+even] // } else { // Sup = _out // } // if x > 0 { // Sleft = previous[x+even-1] // } else { // Sleft = _out // } // } // var score uint64 // switch { // case Sdiag >= Sup && Sdiag >= Sleft: // score = Sdiag // case Sup >= Sleft: // score = Sup // default: // score = Sleft // } // if _isout(Sdiag) || _isout(Sup) || _isout(Sleft) { // score = _setout(score) // } // current[x] = _incpath(score) // } // // . 9 10 + 2 - 1 // x1 = y - lB + extra + even // x2 = extra - y + even - 1 // xs = obiutils.MaxInt(obiutils.MaxInt(x1, x2), even) // x1 = y + extra + even // x2 = lA + extra - y + even - 1 // xf = obiutils.MinInt(obiutils.MinInt(x1, x2), width-1) + 1 // for x := xs; x < xf; x++ { // i := y - x + extra + even // j := y + x - extra - even + 1 // var Sdiag, Sleft, Sup uint64 // switch { // case i == 0: // Sup = _notavail // Sdiag = _notavail // Sleft = encodeValues(0, j-1, false) // case j == 0: // Sup = encodeValues(0, i-1, false) // Sdiag = _notavail // Sleft = _notavail // default: // Sdiag = previous[x] // if bA[j-1] == bB[i-1] { // Sdiag = _incscore(Sdiag) // } // Sleft = current[x-even] // Sup = current[x-even+1] // } // var score uint64 // switch { // case Sdiag >= Sup && Sdiag >= Sleft: // score = Sdiag // case Sup >= Sleft: // score = Sup // default: // score = Sleft // } // if _isout(Sdiag) || _isout(Sup) || _isout(Sleft) { // score = _setout(score) // } // current[x] = _incpath(score) // } // previous, current = current, previous // } // s, l, o := decodeValues(previous[(delta%2)*even+extra+(delta>>1)]) // if o { // return -1, -1 // } // return s, l // }