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