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