github.com/biogo/biogo@v1.0.4/align/nw_affine_letters.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 nw_affine_type.got:17 19 func drawNWAffineTableLetters(rSeq, qSeq alphabet.Letters, index alphabet.Index, table [][3]int, a NWAffine) { 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]) 35 } 36 37 for j := 0; j < c; j++ { 38 p := pointerNWAffineLetters(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 pointerNWAffineLetters(rSeq, qSeq alphabet.Letters, i, j, l int, table [][3]int, index alphabet.Index, a NWAffine, c int) string { 57 switch { 58 case i == 0 && j == 0: 59 return "" 60 case i == 0: 61 if j == 1 { 62 return "⬅ m" 63 } 64 return "⬅ l" 65 case j == 0: 66 if i == 1 { 67 return "⬆ m" 68 } 69 return "⬆ u" 70 } 71 rVal := index[rSeq[i-1]] 72 qVal := index[qSeq[j-1]] 73 if rVal < 0 || qVal < 0 { 74 return "" 75 } 76 switch p := i*c + j; table[p][l] { 77 case table[p-c][up] + a.Matrix[rVal][gap]: 78 return "⬆ u" 79 case table[p-1][left] + a.Matrix[gap][qVal]: 80 return "⬅ l" 81 82 case table[p-c][diag] + a.GapOpen + a.Matrix[rVal][gap]: 83 return "⬆ m" 84 case table[p-1][diag] + a.GapOpen + a.Matrix[gap][qVal]: 85 return "⬅ m" 86 87 case table[p-c-1][up] + a.Matrix[rVal][qVal]: 88 return "⬉ u" 89 case table[p-c-1][left] + a.Matrix[rVal][qVal]: 90 return "⬉ l" 91 case table[p-c-1][diag] + a.Matrix[rVal][qVal]: 92 return "⬉ m" 93 default: 94 return [3]string{"", "⬆ u", "⬅ l"}[l] 95 } 96 } 97 98 func (a NWAffine) alignLetters(rSeq, qSeq alphabet.Letters, alpha alphabet.Alphabet) ([]feat.Pair, error) { 99 let := len(a.Matrix) 100 if let < alpha.Len() { 101 return nil, ErrMatrixWrongSize{Size: let, Len: alpha.Len()} 102 } 103 la := make([]int, 0, let*let) 104 for _, row := range a.Matrix { 105 if len(row) != let { 106 return nil, ErrMatrixNotSquare 107 } 108 la = append(la, row...) 109 } 110 111 index := alpha.LetterIndex() 112 r, c := rSeq.Len()+1, qSeq.Len()+1 113 table := make([][3]int, r*c) 114 table[0] = [3]int{ 115 diag: 0, 116 up: minInt, 117 left: minInt, 118 } 119 table[1] = [3]int{ 120 diag: minInt, 121 up: minInt, 122 left: a.GapOpen + la[index[qSeq[0]]], 123 } 124 for j := range table[2:c] { 125 table[j+2] = [3]int{ 126 diag: minInt, 127 up: minInt, 128 left: table[j+1][left] + la[index[qSeq[j+1]]], 129 } 130 } 131 table[c] = [3]int{ 132 diag: minInt, 133 up: a.GapOpen + la[index[rSeq[0]]*let], 134 left: minInt, 135 } 136 for i := 2; i < r; i++ { 137 table[i*c] = [3]int{ 138 diag: minInt, 139 up: table[(i-1)*c][up] + la[index[rSeq[i-1]]*let], 140 left: minInt, 141 } 142 } 143 144 for i := 1; i < r; i++ { 145 for j := 1; j < c; j++ { 146 var ( 147 rVal = index[rSeq[i-1]] 148 qVal = index[qSeq[j-1]] 149 ) 150 if rVal < 0 { 151 return nil, fmt.Errorf("align: illegal letter %q at position %d in rSeq", rSeq[i-1], i-1) 152 } 153 if qVal < 0 { 154 return nil, fmt.Errorf("align: illegal letter %q at position %d in qSeq", qSeq[j-1], j-1) 155 } 156 p := i*c + j 157 158 diagScore := table[p-c-1][diag] 159 upScore := table[p-c-1][up] 160 leftScore := table[p-c-1][left] 161 162 table[p][diag] = max3(diagScore, upScore, leftScore) + la[rVal*let+qVal] 163 164 table[p][up] = max2( 165 add(table[p-c][diag], a.GapOpen+la[rVal*let]), 166 add(table[p-c][up], la[rVal*let]), 167 ) 168 169 table[p][left] = max2( 170 add(table[p-1][diag], a.GapOpen+la[qVal]), 171 add(table[p-1][left], la[qVal]), 172 ) 173 } 174 } 175 if debugNeedleAffine { 176 drawNWAffineTableLetters(rSeq, qSeq, index, table, a) 177 } 178 179 var ( 180 aln []feat.Pair 181 layer int 182 ) 183 score, last := 0, diag 184 i, j := r-1, c-1 185 t := table[i*c+j] 186 best := t[0] 187 for i, s := range t[1:] { 188 if s > best { 189 best, layer = s, i+1 190 } 191 } 192 maxI, maxJ := i, j 193 for i > 0 && j > 0 { 194 var ( 195 rVal = index[rSeq[i-1]] 196 qVal = index[qSeq[j-1]] 197 ) 198 switch p := i*c + j; table[p][layer] { 199 case table[p-c][up] + la[rVal*let]: 200 if last != up && p != len(table)-1 { 201 aln = append(aln, &featPair{ 202 a: feature{start: i, end: maxI}, 203 b: feature{start: j, end: maxJ}, 204 score: score, 205 }) 206 maxI, maxJ = i, j 207 score = 0 208 } 209 score += table[p][layer] - table[p-c][up] 210 i-- 211 layer = up 212 last = up 213 case table[p-1][left] + la[qVal]: 214 if last != left && p != len(table)-1 { 215 aln = append(aln, &featPair{ 216 a: feature{start: i, end: maxI}, 217 b: feature{start: j, end: maxJ}, 218 score: score, 219 }) 220 maxI, maxJ = i, j 221 score = 0 222 } 223 score += table[p][layer] - table[p-1][left] 224 j-- 225 layer = left 226 last = left 227 case table[p-c][diag] + a.GapOpen + la[rVal*let]: 228 if last != up && p != len(table)-1 { 229 aln = append(aln, &featPair{ 230 a: feature{start: i, end: maxI}, 231 b: feature{start: j, end: maxJ}, 232 score: score, 233 }) 234 maxI, maxJ = i, j 235 score = 0 236 } 237 score += table[p][layer] - table[p-c][diag] 238 i-- 239 layer = diag 240 last = up 241 case table[p-1][diag] + a.GapOpen + la[qVal]: 242 if last != left && p != len(table)-1 { 243 aln = append(aln, &featPair{ 244 a: feature{start: i, end: maxI}, 245 b: feature{start: j, end: maxJ}, 246 score: score, 247 }) 248 maxI, maxJ = i, j 249 score = 0 250 } 251 score += table[p][layer] - table[p-1][diag] 252 j-- 253 layer = diag 254 last = left 255 case table[p-c-1][up] + la[rVal*let+qVal]: 256 if last != diag { 257 aln = append(aln, &featPair{ 258 a: feature{start: i, end: maxI}, 259 b: feature{start: j, end: maxJ}, 260 score: score, 261 }) 262 maxI, maxJ = i, j 263 score = 0 264 } 265 score += table[p][layer] - table[p-c-1][up] 266 i-- 267 j-- 268 layer = up 269 last = diag 270 case table[p-c-1][left] + la[rVal*let+qVal]: 271 if last != diag { 272 aln = append(aln, &featPair{ 273 a: feature{start: i, end: maxI}, 274 b: feature{start: j, end: maxJ}, 275 score: score, 276 }) 277 maxI, maxJ = i, j 278 score = 0 279 } 280 score += table[p][layer] - table[p-c-1][left] 281 i-- 282 j-- 283 layer = left 284 last = diag 285 case table[p-c-1][diag] + la[rVal*let+qVal]: 286 if last != diag { 287 aln = append(aln, &featPair{ 288 a: feature{start: i, end: maxI}, 289 b: feature{start: j, end: maxJ}, 290 score: score, 291 }) 292 maxI, maxJ = i, j 293 score = 0 294 } 295 score += table[p][layer] - table[p-c-1][diag] 296 i-- 297 j-- 298 layer = diag 299 last = diag 300 301 default: 302 panic(fmt.Sprintf("align: nw affine internal error: no path at row: %d col:%d layer:%s\n", i, j, "mul"[layer:layer+1])) 303 } 304 } 305 306 aln = append(aln, &featPair{ 307 a: feature{start: i, end: maxI}, 308 b: feature{start: j, end: maxJ}, 309 score: score, 310 }) 311 if i != j { 312 switch 0 { 313 case i: 314 last = left 315 case j: 316 last = up 317 default: 318 panic(fmt.Sprintf("align: nw affine internal error: unexpected final segment: row: %d col: %d", i, j)) 319 } 320 aln = append(aln, &featPair{ 321 a: feature{start: 0, end: i}, 322 b: feature{start: 0, end: j}, 323 score: table[i*c+j][last], 324 }) 325 } 326 327 for i, j := 0, len(aln)-1; i < j; i, j = i+1, j-1 { 328 aln[i], aln[j] = aln[j], aln[i] 329 } 330 331 return aln, nil 332 }