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