github.com/biogo/biogo@v1.0.4/align/sw_affine_type.got (about)

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