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