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