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