github.com/biogo/biogo@v1.0.4/align/sw_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 sw_type.got:17 19 func drawSWTableLetters(rSeq, qSeq alphabet.Letters, index alphabet.Index, table []int, a [][]int) { 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 fmt.Fprint(tw, "\tqSeq\t") 24 for _, l := range qSeq { 25 fmt.Fprintf(tw, "%c\t", l) 26 } 27 fmt.Fprintln(tw) 28 29 r, c := rSeq.Len()+1, qSeq.Len()+1 30 fmt.Fprint(tw, "rSeq\t") 31 for i := 0; i < r; i++ { 32 if i != 0 { 33 fmt.Fprintf(tw, "%c\t", rSeq[i-1]) 34 } 35 36 for j := 0; j < c; j++ { 37 p := pointerSWLetters(rSeq, qSeq, i, j, table, index, a, c) 38 fmt.Fprintf(tw, "%s %3v\t", p, table[i*c+j]) 39 } 40 fmt.Fprintln(tw) 41 } 42 tw.Flush() 43 } 44 45 func pointerSWLetters(rSeq, qSeq alphabet.Letters, i, j int, table []int, index alphabet.Index, a [][]int, c int) string { 46 if i == 0 || j == 0 { 47 return " " 48 } 49 rVal := index[rSeq[i-1]] 50 qVal := index[qSeq[j-1]] 51 if rVal < 0 || qVal < 0 { 52 return " " 53 } 54 switch p := i*c + j; { 55 case table[p] == 0: 56 return " " 57 case table[p-c-1]+a[rVal][qVal] == table[p] && table[p-c-1] != 0: 58 return "⬉" 59 case table[p-c]+a[rVal][gap] == table[p] && table[p-c] != 0: 60 return "⬆" 61 case table[p-1]+a[gap][qVal] == table[p] && table[p-1] != 0: 62 return "⬅" 63 default: 64 return "⌜" 65 } 66 } 67 68 func (a SW) alignLetters(rSeq, qSeq alphabet.Letters, alpha alphabet.Alphabet) ([]feat.Pair, error) { 69 let := len(a) 70 if let < alpha.Len() { 71 return nil, ErrMatrixWrongSize{Size: let, Len: alpha.Len()} 72 } 73 la := make([]int, 0, let*let) 74 for _, row := range a { 75 if len(row) != let { 76 return nil, ErrMatrixNotSquare 77 } 78 la = append(la, row...) 79 } 80 r, c := rSeq.Len()+1, qSeq.Len()+1 81 table := make([]int, r*c) 82 83 var ( 84 index = alpha.LetterIndex() 85 86 maxS, maxI, maxJ = 0, 0, 0 87 88 score int 89 ) 90 91 for i := 1; i < r; i++ { 92 for j := 1; j < c; j++ { 93 var ( 94 rVal = index[rSeq[i-1]] 95 qVal = index[qSeq[j-1]] 96 ) 97 if rVal < 0 { 98 return nil, fmt.Errorf("align: illegal letter %q at position %d in rSeq", rSeq[i-1], i-1) 99 } 100 if qVal < 0 { 101 return nil, fmt.Errorf("align: illegal letter %q at position %d in qSeq", qSeq[j-1], j-1) 102 } 103 p := i*c + j 104 105 diagScore := table[p-c-1] + la[rVal*let+qVal] 106 upScore := table[p-c] + la[rVal*let] 107 leftScore := table[p-1] + la[qVal] 108 109 score = max3(diagScore, upScore, leftScore) 110 switch { 111 case score > 0: 112 if score >= maxS && score == diagScore { 113 maxS, maxI, maxJ = score, i, j 114 } 115 default: 116 score = 0 117 } 118 table[p] = score 119 } 120 } 121 if debugSmith { 122 drawSWTableLetters(rSeq, qSeq, index, table, a) 123 } 124 125 var aln []feat.Pair 126 score, last := 0, diag 127 i, j := maxI, maxJ 128 loop: 129 for i > 0 && j > 0 { 130 var ( 131 rVal = index[rSeq[i-1]] 132 qVal = index[qSeq[j-1]] 133 ) 134 switch p := i*c + j; table[p] { 135 case 0: 136 break loop 137 case table[p-c-1] + la[rVal*let+qVal]: 138 if last != diag { 139 aln = append(aln, &featPair{ 140 a: feature{start: i, end: maxI}, 141 b: feature{start: j, end: maxJ}, 142 score: score, 143 }) 144 maxI, maxJ = i, j 145 score = 0 146 } 147 score += table[p] - table[p-c-1] 148 i-- 149 j-- 150 last = diag 151 case table[p-c] + la[rVal*let]: 152 if last != up { 153 aln = append(aln, &featPair{ 154 a: feature{start: i, end: maxI}, 155 b: feature{start: j, end: maxJ}, 156 score: score, 157 }) 158 maxI, maxJ = i, j 159 score = 0 160 } 161 score += table[p] - table[p-c] 162 i-- 163 last = up 164 case table[p-1] + la[qVal]: 165 if last != left { 166 aln = append(aln, &featPair{ 167 a: feature{start: i, end: maxI}, 168 b: feature{start: j, end: maxJ}, 169 score: score, 170 }) 171 maxI, maxJ = i, j 172 score = 0 173 } 174 score += table[p] - table[p-1] 175 j-- 176 last = left 177 default: 178 panic(fmt.Sprintf("align: sw internal error: no path at row: %d col:%d\n", i, j)) 179 } 180 } 181 182 aln = append(aln, &featPair{ 183 a: feature{start: i, end: maxI}, 184 b: feature{start: j, end: maxJ}, 185 score: score, 186 }) 187 188 for i, j := 0, len(aln)-1; i < j; i, j = i+1, j-1 { 189 aln[i], aln[j] = aln[j], aln[i] 190 } 191 192 return aln, nil 193 }