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  }