change the model for representing paired reads and extend its usage to other commands

This commit is contained in:
2023-02-23 23:35:58 +01:00
parent ebb05fcdf7
commit 072b85e155
23 changed files with 598 additions and 338 deletions

View File

@@ -55,6 +55,7 @@ type BioSequence struct {
sequence []byte // The sequence itself, it is accessible by the methode Sequence
qualities []byte // The quality scores of the sequence.
feature []byte
paired *BioSequence // A pointer to the paired sequence
annotations Annotation
}
@@ -69,6 +70,7 @@ func MakeEmptyBioSequence() BioSequence {
sequence: nil,
qualities: nil,
feature: nil,
paired: nil,
annotations: nil,
}
}
@@ -275,3 +277,4 @@ func (s *BioSequence) WriteByte(data byte) error {
func (s *BioSequence) Clear() {
s.sequence = s.sequence[0:0]
}

View File

@@ -23,7 +23,7 @@ func NewBioSequenceSlice(size ...int) *BioSequenceSlice {
slice := _BioSequenceSlicePool.Get().(*BioSequenceSlice)
if len(size) > 0 {
s := size[0]
slice.InsureCapacity(s)
slice = slice.InsureCapacity(s)
(*slice)=(*slice)[0:s]
}
return slice

View File

@@ -0,0 +1,58 @@
package obiseq
import log "github.com/sirupsen/logrus"
func (s *BioSequence) IsPaired() bool {
return s.paired != nil
}
func (s *BioSequence) PairedWith() *BioSequence {
return s.paired
}
func (s *BioSequence) PairTo(p *BioSequence) {
s.paired = p
if p != nil {
p.paired = s
}
}
func (s *BioSequence) UnPair() {
if s.paired != nil {
s.paired.paired = nil
}
s.paired = nil
}
func (s *BioSequenceSlice) IsPaired() bool {
return (*s)[0].paired != nil
}
func (s *BioSequenceSlice) PairedWith() *BioSequenceSlice {
ps := NewBioSequenceSlice(len(*s))
for i, seq := range *s {
(*ps)[i] = seq.PairedWith()
}
return ps
}
func (s *BioSequenceSlice) PairTo(p *BioSequenceSlice) {
if len(*s) != len(*p) {
log.Fatalf("Pairing of iterators: both batches have not the same length : (%d,%d)",
len(*s), len(*p),
)
}
for i, seq := range *s {
seq.PairTo((*p)[i])
}
}
func (s *BioSequenceSlice) UnPair() {
for _, seq := range *s {
seq.UnPair()
}
}

View File

@@ -11,6 +11,61 @@ import (
type SequencePredicate func(*BioSequence) bool
type SeqPredicateMode int
const (
ForwardOnly SeqPredicateMode = iota
ReverseOnly
And
Or
AndNot
Xor
)
func (predicate SequencePredicate) PredicateOnPaired(ifnotpaired bool) SequencePredicate {
if predicate == nil {
return nil
}
p := func(sequence *BioSequence) bool {
if sequence.IsPaired() {
return predicate(sequence.PairedWith())
}
return ifnotpaired
}
return p
}
func (predicate SequencePredicate) PairedPredicat(mode SeqPredicateMode) SequencePredicate {
if predicate == nil {
return nil
}
p := func(sequence *BioSequence) bool {
good := predicate(sequence)
if sequence.IsPaired() && mode != ForwardOnly {
pgood := predicate(sequence.PairedWith())
switch mode {
case ReverseOnly:
good = pgood
case And:
good = good && pgood
case Or:
good = good || pgood
case AndNot:
good = good && !pgood
case Xor:
good = (good || pgood) && !(good && pgood)
}
}
return good
}
return p
}
func (predicate1 SequencePredicate) And(predicate2 SequencePredicate) SequencePredicate {
switch {
case predicate1 == nil:
@@ -209,8 +264,8 @@ func ExpressionPredicat(expression string) SequencePredicate {
f := func(sequence *BioSequence) bool {
value, err := exp.EvalBool(context.Background(),
map[string]interface{}{
"annotations": sequence.Annotations(),
"sequence": sequence,
"annotations": sequence.Annotations(),
"sequence": sequence,
},
)
@@ -225,4 +280,3 @@ func ExpressionPredicat(expression string) SequencePredicate {
return f
}