github.com/biogo/biogo@v1.0.4/align/fitted_affine_qletters.go (about) 1 // This file is automatically generated. Do not edit - make changes to relevant got file. 2 3 // Copyright ©2011-2012 The bíogo Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 package align 8 9 import ( 10 "github.com/biogo/biogo/alphabet" 11 "github.com/biogo/biogo/feat" 12 13 "fmt" 14 "os" 15 "text/tabwriter" 16 ) 17 18 //line fitted_affine_type.got:17 19 func drawFittedAffineTableQLetters(rSeq, qSeq alphabet.QLetters, index alphabet.Index, table [][3]int, a FittedAffine) { 20 tw := tabwriter.NewWriter(os.Stdout, 0, 0, 0, ' ', tabwriter.AlignRight|tabwriter.Debug) 21 fmt.Printf("rSeq: %s\n", rSeq) 22 fmt.Printf("qSeq: %s\n", qSeq) 23 for l := 0; l < 3; l++ { 24 fmt.Fprintf(tw, "%c\tqSeq\t", "MUL"[l]) 25 for _, l := range qSeq { 26 fmt.Fprintf(tw, "%c\t", l) 27 } 28 fmt.Fprintln(tw) 29 30 r, c := rSeq.Len()+1, qSeq.Len()+1 31 fmt.Fprint(tw, "rSeq\t") 32 for i := 0; i < r; i++ { 33 if i != 0 { 34 fmt.Fprintf(tw, "%c\t", rSeq[i-1].L) 35 } 36 37 for j := 0; j < c; j++ { 38 p := pointerFittedAffineQLetters(rSeq, qSeq, i, j, l, table, index, a, c) 39 var vi interface{} 40 if vi = table[i*c+j][l]; vi == minInt { 41 vi = "-Inf" 42 } 43 if p != "" { 44 fmt.Fprintf(tw, "%s % 4v\t", p, vi) 45 } else { 46 fmt.Fprintf(tw, "%v\t", vi) 47 } 48 } 49 fmt.Fprintln(tw) 50 } 51 fmt.Fprintln(tw) 52 } 53 tw.Flush() 54 } 55 56 func pointerFittedAffineQLetters(rSeq, qSeq alphabet.QLetters, i, j, l int, table [][3]int, index alphabet.Index, a FittedAffine, c int) string { 57 if j == 0 { 58 return "" 59 } 60 if i == 0 { 61 if l == left { 62 return "⬅ l" 63 } 64 return "" 65 } 66 rVal := index[rSeq[i-1].L] 67 qVal := index[qSeq[j-1].L] 68 if rVal < 0 || qVal < 0 { 69 return "" 70 } 71 switch p := i*c + j; table[p][l] { 72 case table[p-c][up] + a.Matrix[rVal][gap]: 73 return "⬆ u" 74 case table[p-1][left] + a.Matrix[gap][qVal]: 75 return "⬅ l" 76 77 case table[p-c][diag] + a.GapOpen + a.Matrix[rVal][gap]: 78 return "⬆ m" 79 case table[p-1][diag] + a.GapOpen + a.Matrix[gap][qVal]: 80 return "⬅ m" 81 82 case table[p-c-1][up] + a.Matrix[rVal][qVal]: 83 return "⬉ u" 84 case table[p-c-1][left] + a.Matrix[rVal][qVal]: 85 return "⬉ l" 86 case table[p-c-1][diag] + a.Matrix[rVal][qVal]: 87 return "⬉ m" 88 default: 89 return [3]string{"", "⬆ u", "⬅ l"}[l] 90 } 91 } 92 93 func (a FittedAffine) alignQLetters(rSeq, qSeq alphabet.QLetters, alpha alphabet.Alphabet) ([]feat.Pair, error) { 94 let := len(a.Matrix) 95 la := make([]int, 0, let*let) 96 for _, row := range a.Matrix { 97 if len(row) != let { 98 return nil, ErrMatrixNotSquare 99 } 100 la = append(la, row...) 101 } 102 103 index := alpha.LetterIndex() 104 r, c := rSeq.Len()+1, qSeq.Len()+1 105 table := make([][3]int, r*c) 106 table[0] = [3]int{ 107 diag: 0, 108 up: minInt, 109 left: minInt, 110 } 111 table[1] = [3]int{ 112 diag: minInt, 113 up: minInt, 114 } 115 table[1][left] = a.GapOpen + la[index[qSeq[0].L]] 116 for j := range table[2:c] { 117 table[j+2] = [3]int{ 118 diag: minInt, 119 up: minInt, 120 left: table[j+1][left] + la[index[qSeq[j+1].L]], 121 } 122 } 123 table[c] = [3]int{ 124 diag: minInt, 125 left: minInt, 126 } 127 for i := 2; i < r; i++ { 128 table[i*c] = [3]int{ 129 diag: minInt, 130 left: minInt, 131 } 132 } 133 134 for i := 1; i < r; i++ { 135 for j := 1; j < c; j++ { 136 var ( 137 rVal = index[rSeq[i-1].L] 138 qVal = index[qSeq[j-1].L] 139 ) 140 if rVal < 0 { 141 return nil, fmt.Errorf("align: illegal letter %q at position %d in rSeq", rSeq[i-1].L, i-1) 142 } 143 if qVal < 0 { 144 return nil, fmt.Errorf("align: illegal letter %q at position %d in qSeq", qSeq[j-1].L, j-1) 145 } 146 p := i*c + j 147 148 diagScore := table[p-c-1][diag] 149 upScore := table[p-c-1][up] 150 leftScore := table[p-c-1][left] 151 152 table[p][diag] = max3(diagScore, upScore, leftScore) + la[rVal*let+qVal] 153 154 table[p][up] = max2( 155 add(table[p-c][diag], a.GapOpen+la[rVal*let]), 156 add(table[p-c][up], la[rVal*let]), 157 ) 158 159 table[p][left] = max2( 160 add(table[p-1][diag], a.GapOpen+la[qVal]), 161 add(table[p-1][left], la[qVal]), 162 ) 163 } 164 } 165 if debugFittedAffine { 166 drawFittedAffineTableQLetters(rSeq, qSeq, index, table, a) 167 } 168 169 var aln []feat.Pair 170 score, last, layer := 0, diag, diag 171 var ( 172 i int 173 j = c - 1 174 ) 175 max := minInt 176 for y := 1; y < r; y++ { 177 v := table[(y*c)+c-1][diag] 178 if v >= max { 179 i = y 180 max = v 181 } 182 } 183 maxI, maxJ := i, j 184 for i > 0 && j > 0 { 185 var ( 186 rVal = index[rSeq[i-1].L] 187 qVal = index[qSeq[j-1].L] 188 ) 189 switch p := i*c + j; table[p][layer] { 190 case table[p-c][up] + la[rVal*let]: 191 if last != up && p != len(table)-1 { 192 aln = append(aln, &featPair{ 193 a: feature{start: i, end: maxI}, 194 b: feature{start: j, end: maxJ}, 195 score: score, 196 }) 197 maxI, maxJ = i, j 198 score = 0 199 } 200 score += table[p][layer] - table[p-c][up] 201 i-- 202 layer = up 203 last = up 204 case table[p-1][left] + la[qVal]: 205 if last != left && p != len(table)-1 { 206 aln = append(aln, &featPair{ 207 a: feature{start: i, end: maxI}, 208 b: feature{start: j, end: maxJ}, 209 score: score, 210 }) 211 maxI, maxJ = i, j 212 score = 0 213 } 214 score += table[p][layer] - table[p-1][left] 215 j-- 216 layer = left 217 last = left 218 case table[p-c][diag] + a.GapOpen + la[rVal*let]: 219 if last != up && p != len(table)-1 { 220 aln = append(aln, &featPair{ 221 a: feature{start: i, end: maxI}, 222 b: feature{start: j, end: maxJ}, 223 score: score, 224 }) 225 maxI, maxJ = i, j 226 score = 0 227 } 228 score += table[p][layer] - table[p-c][diag] 229 i-- 230 layer = diag 231 last = up 232 case table[p-1][diag] + a.GapOpen + la[qVal]: 233 if last != left && p != len(table)-1 { 234 aln = append(aln, &featPair{ 235 a: feature{start: i, end: maxI}, 236 b: feature{start: j, end: maxJ}, 237 score: score, 238 }) 239 maxI, maxJ = i, j 240 score = 0 241 } 242 score += table[p][layer] - table[p-1][diag] 243 j-- 244 layer = diag 245 last = left 246 case table[p-c-1][up] + la[rVal*let+qVal]: 247 if last != diag { 248 aln = append(aln, &featPair{ 249 a: feature{start: i, end: maxI}, 250 b: feature{start: j, end: maxJ}, 251 score: score, 252 }) 253 maxI, maxJ = i, j 254 score = 0 255 } 256 score += table[p][layer] - table[p-c-1][up] 257 i-- 258 j-- 259 layer = up 260 last = diag 261 case table[p-c-1][left] + la[rVal*let+qVal]: 262 if last != diag { 263 aln = append(aln, &featPair{ 264 a: feature{start: i, end: maxI}, 265 b: feature{start: j, end: maxJ}, 266 score: score, 267 }) 268 maxI, maxJ = i, j 269 score = 0 270 } 271 score += table[p][layer] - table[p-c-1][left] 272 i-- 273 j-- 274 layer = left 275 last = diag 276 case table[p-c-1][diag] + la[rVal*let+qVal]: 277 if last != diag { 278 aln = append(aln, &featPair{ 279 a: feature{start: i, end: maxI}, 280 b: feature{start: j, end: maxJ}, 281 score: score, 282 }) 283 maxI, maxJ = i, j 284 score = 0 285 } 286 score += table[p][layer] - table[p-c-1][diag] 287 i-- 288 j-- 289 layer = diag 290 last = diag 291 292 default: 293 panic(fmt.Sprintf("align: fitted nw affine internal error: no path at row: %d col:%d layer:%s\n", i, j, "mul"[layer:layer+1])) 294 } 295 } 296 297 aln = append(aln, &featPair{ 298 a: feature{start: i, end: maxI}, 299 b: feature{start: j, end: maxJ}, 300 score: score, 301 }) 302 303 for i, j := 0, len(aln)-1; i < j; i, j = i+1, j-1 { 304 aln[i], aln[j] = aln[j], aln[i] 305 } 306 307 return aln, nil 308 }