コード例 #1
0
ファイル: multi.go プロジェクト: frogs/biogo
func (self *Multi) Stitch(f feat.FeatureSet) (err error) {
	tr := interval.NewTree()
	var i *interval.Interval

	for _, feature := range f {
		i, err = interval.New(emptyString, feature.Start, feature.End, 0, nil)
		if err != nil {
			return
		} else {
			tr.Insert(i)
		}
	}

	span, err := interval.New(emptyString, self.Start(), self.End(), 0, nil)
	if err != nil {
		panic("Sequence.End() < Sequence.Start()")
	}
	fs, _ := tr.Flatten(span, 0, 0)

	ff := feat.FeatureSet{}
	for _, seg := range fs {
		ff = append(ff, &feat.Feature{
			Start: util.Max(seg.Start(), self.Start()),
			End:   util.Min(seg.End(), self.End()),
		})
	}

	return self.Compose(ff)
}
コード例 #2
0
ファイル: utils.go プロジェクト: frogs/biogo
// Stitch provides a function that may be used by polymer types to implement Stitcher.
// It makes use of reflection and so may be slower than type-specific implementations.
// This is the reference implementation and should be used to compare type-specific
// implementation against in testing.
func Stitch(pol interface{}, offset int, f feat.FeatureSet) (s interface{}, err error) {
	t := interval.NewTree()
	var i *interval.Interval

	for _, feature := range f {
		i, err = interval.New(emptyString, feature.Start, feature.End, 0, nil)
		if err != nil {
			return
		} else {
			t.Insert(i)
		}
	}

	pv := reflect.ValueOf(pol)
	pLen := pv.Len()
	end := pLen + offset
	span, err := interval.New(emptyString, offset, end, 0, nil)
	if err != nil {
		panic("Sequence.End() < Sequence.Start()")
	}
	fs, _ := t.Flatten(span, 0, 0)
	l := 0

	for _, seg := range fs {
		l += util.Min(seg.End(), end) - util.Max(seg.Start(), offset)
	}
	tv := reflect.MakeSlice(pv.Type(), 0, l)

	for _, seg := range fs {
		tv = reflect.AppendSlice(tv, pv.Slice(util.Max(seg.Start()-offset, 0), util.Min(seg.End()-offset, pLen)))
	}

	return tv.Interface(), nil
}
コード例 #3
0
ファイル: packed.go プロジェクト: frogs/biogo
// Join sequentially order disjunct segments of the sequence, returning any error.
func (self *Seq) Stitch(f feat.FeatureSet) (err error) {
	tr := interval.NewTree()
	var i *interval.Interval

	for _, feature := range f {
		i, err = interval.New(emptyString, feature.Start, feature.End, 0, nil)
		if err != nil {
			return
		} else {
			tr.Insert(i)
		}
	}

	span, err := interval.New(emptyString, self.offset, self.End(), 0, nil)
	if err != nil {
		panic("packed: Sequence.End() < Sequence.Start()")
	}
	fs, _ := tr.Flatten(span, 0, 0)
	l := 0

	for _, seg := range fs {
		l += util.Min(seg.End(), self.End()) - util.Max(seg.Start(), self.Start())
	}

	t := &Seq{}
	*t = *self
	t.S = &Packing{Letters: make([]alphabet.Pack, 0, (l+3)/4)}

	var tseg seq.Sequence
	for _, seg := range fs {
		tseg, err = self.Subseq(util.Max(seg.Start(), self.Start()), util.Min(seg.End(), self.End()))
		if err != nil {
			return
		}
		s := tseg.(*Seq).S
		s.Align(seq.Start)
		t.S.Align(seq.End)
		t.S.Letters = append(t.S.Letters, s.Letters...)
		t.S.RightPad = s.RightPad
	}

	*self = *t

	return
}
コード例 #4
0
ファイル: qual.go プロジェクト: frogs/biogo
func (self *Quality) Stitch(f feat.FeatureSet) (q *Quality, err error) {
	t := interval.NewTree()
	var i *interval.Interval

	for _, feature := range f {
		i, err = interval.New(emptyString, feature.Start, feature.End, 0, nil)
		if err != nil {
			return
		} else {
			t.Insert(i)
		}
	}

	span, err := interval.New(emptyString, self.Start(), self.End(), 0, nil)
	if err != nil {
		panic("Seq.End() < Seq.Start()")
	}

	fs, _ := t.Flatten(span, 0, 0)
	if self.Inplace {
		q = self
		q.Qual = self.stitch(fs)
		q.Offset = 0
		q.Circular = false
	} else {
		q = &Quality{
			ID:       self.ID,
			Qual:     self.stitch(fs),
			Offset:   0,
			Strand:   self.Strand,
			Circular: false,
		}
	}

	return
}
コード例 #5
0
ファイル: seq.go プロジェクト: frogs/biogo
func (self *Seq) Stitch(f feat.FeatureSet) (s *Seq, err error) {
	if !self.Inplace && self.Quality != nil && self.Quality.Inplace {
		return nil, bio.NewError("Inplace operation on Quality with non-Inplace operation on parent Seq.", 0, self)
	}

	t := interval.NewTree()
	var i *interval.Interval

	for _, feature := range f {
		i, err = interval.New(emptyString, feature.Start, feature.End, 0, nil)
		if err != nil {
			return
		} else {
			t.Insert(i)
		}
	}

	span, err := interval.New(emptyString, self.Start(), self.End(), 0, nil)
	if err != nil {
		panic("Seq.End() < Seq.Start()")
	}
	fs, _ := t.Flatten(span, 0, 0)

	if self.Inplace {
		self.Seq = self.stitch(fs)
		self.Offset = 0
		self.Circular = false
		if self.Quality != nil {
			var q *Quality
			if !self.Quality.Inplace {
				q = &Quality{ID: self.Quality.ID}
			}
			q.Qual = self.Quality.stitch(fs)
			q.Offset = 0
			q.Circular = false
			self.Quality = q
		}
		s = self
	} else {
		var q *Quality
		if self.Quality != nil {
			q = &Quality{
				ID:       self.Quality.ID,
				Qual:     self.Quality.stitch(fs),
				Offset:   0,
				Circular: false,
			}
		}
		s = &Seq{
			ID:       self.ID,
			Seq:      self.stitch(fs),
			Offset:   0,
			Strand:   self.Strand,
			Circular: false,
			Moltype:  self.Moltype,
			Quality:  q,
		}
	}

	return
}
コード例 #6
0
ファイル: alignment.go プロジェクト: frogs/biogo
func (self Alignment) Stitch(f feat.FeatureSet) (a Alignment, err error) {
	for _, s := range self {
		if !s.Inplace && s.Quality != nil && s.Quality.Inplace {
			return nil, bio.NewError("Inplace operation on Quality with non-Inplace operation on parent Seq.", 0, s)
		}
	}

	t := interval.NewTree()
	var i *interval.Interval

	for _, feature := range f {
		i, err = interval.New("", feature.Start, feature.End, 0, nil)
		if err != nil {
			return
		} else {
			t.Insert(i)
		}
	}

	start := self.Start()
	a = make(Alignment, len(self))
	span, err := interval.New("", start, self.End(), 0, nil)
	if err != nil {
		panic("Seq.End() < Seq.Start()")
	}
	fs, _ := t.Flatten(span, 0, 0)

	var offset int
	for i, s := range self {
		if s.Inplace {
			s.Seq = s.stitch(fs)
			if s.Offset -= fs[0].Start(); offset < 0 {
				s.Offset = 0
			}
			s.Circular = false
			if s.Quality != nil {
				var q *Quality
				if s.Quality.Inplace {
					q = s.Quality
				} else {
					q = &Quality{ID: s.Quality.ID}
				}
				q.Qual = s.Quality.stitch(fs)
				if q.Offset = s.Quality.Offset - fs[0].Start(); q.Offset < 0 {
					q.Offset = 0
				}
				q.Circular = false
				s.Quality = q
			}
			a[i] = s
		} else {
			var q *Quality
			if s.Quality != nil {
				if offset = s.Quality.Offset - fs[0].Start(); offset < 0 {
					offset = 0
				}
				q = &Quality{
					ID:       s.Quality.ID,
					Qual:     s.Quality.stitch(fs),
					Offset:   offset,
					Circular: false,
				}
			}
			if offset = s.Offset - fs[0].Start(); offset < 0 {
				offset = 0
			}
			a[i] = &Seq{
				ID:       s.ID,
				Seq:      s.stitch(fs),
				Offset:   offset,
				Strand:   s.Strand,
				Circular: false,
				Moltype:  s.Moltype,
				Quality:  q,
			}
		}
	}

	return
}