github.com/biogo/biogo@v1.0.4/align/pals/pair.go (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 pals
     6  
     7  import (
     8  	"github.com/biogo/biogo/align/pals/dp"
     9  	"github.com/biogo/biogo/io/featio/gff"
    10  	"github.com/biogo/biogo/seq"
    11  
    12  	"fmt"
    13  	"strconv"
    14  	"strings"
    15  )
    16  
    17  // A Pair holds a pair of features with additional information relating the two.
    18  type Pair struct {
    19  	A, B   *Feature
    20  	Score  int        // Score of alignment between features.
    21  	Error  float64    // Identity difference between feature sequences.
    22  	Strand seq.Strand // Strand relationship: seq.Plus indicates same strand, seq.Minus indicates opposite strand.
    23  }
    24  
    25  func (fp *Pair) String() string {
    26  	if fp == nil {
    27  		return "<nil>"
    28  	}
    29  	return fmt.Sprintf("%s/%s[%d,%d)--%s/%s[%d,%d)",
    30  		fp.A.Location().Name(), fp.A.Name(), fp.A.Start(), fp.A.End(),
    31  		fp.B.Location().Name(), fp.B.Name(), fp.B.Start(), fp.B.End(),
    32  	)
    33  }
    34  
    35  // NewPair converts a dp.Hit and two packed sequences into a Pair.
    36  func NewPair(target, query *Packed, hit dp.Hit, comp bool) (*Pair, error) {
    37  	t, err := target.feature(hit.Abpos, hit.Aepos, false)
    38  	if err != nil {
    39  		return nil, err
    40  	}
    41  	q, err := query.feature(hit.Bbpos, hit.Bepos, comp)
    42  	if err != nil {
    43  		return nil, err
    44  	}
    45  
    46  	var strand seq.Strand
    47  	if comp {
    48  		strand = -1
    49  	} else {
    50  		strand = 1
    51  	}
    52  
    53  	return &Pair{
    54  		A:      t,
    55  		B:      q,
    56  		Score:  hit.Score,
    57  		Error:  hit.Error,
    58  		Strand: strand,
    59  	}, nil
    60  }
    61  
    62  // ExpandFeature converts a *gff.Feature containing PALS-type feature attributes into a Pair.
    63  func ExpandFeature(f *gff.Feature) (*Pair, error) {
    64  	targ := f.FeatAttributes.Get("Target")
    65  	if targ == "" {
    66  		return nil, fmt.Errorf("pals: not a feature pair")
    67  	}
    68  	fields := strings.Fields(targ)
    69  	if len(fields) != 3 {
    70  		return nil, fmt.Errorf("pals: not a feature pair")
    71  	}
    72  
    73  	s, err := strconv.Atoi(fields[1])
    74  	if err != nil {
    75  		return nil, err
    76  	}
    77  	s--
    78  	e, err := strconv.Atoi(fields[2])
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	maxe, err := strconv.ParseFloat(f.FeatAttributes.Get("maxe"), 64)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  
    88  	fp := &Pair{
    89  		A: &Feature{
    90  			ID:   fmt.Sprintf("%s:%d..%d", f.SeqName, f.FeatStart, f.FeatEnd),
    91  			Loc:  Contig(f.SeqName),
    92  			From: f.FeatStart,
    93  			To:   f.FeatEnd,
    94  		},
    95  		B: &Feature{
    96  			ID:   fmt.Sprintf("%s:%d..%s", fields[0], s, fields[2]),
    97  			Loc:  Contig(fields[0]),
    98  			From: s,
    99  			To:   e,
   100  		},
   101  		Score:  int(*f.FeatScore),
   102  		Error:  maxe,
   103  		Strand: f.FeatStrand,
   104  	}
   105  	fp.A.Pair = fp
   106  	fp.B.Pair = fp
   107  	f.FeatScore = nil
   108  	f.FeatAttributes = nil
   109  	f.FeatStrand = seq.None
   110  
   111  	return fp, nil
   112  }