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