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