File: interval.go

package info (click to toggle)
golang-github-brentp-irelate 0.0.1%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 12,624 kB
  • sloc: makefile: 10; python: 5; sh: 4
file content (90 lines) | stat: -rw-r--r-- 2,309 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
package parsers

import (
	"bytes"
	"strconv"
	"strings"
	"unsafe"

	"github.com/brentp/irelate/interfaces"
)

const empty = ""

// Interval satisfies the Relatable interface.
type Interval struct {
	// chrom, start, end, line, source, related[]
	chrom   string
	start   uint32
	end     uint32
	source  uint32
	Fields  [][]byte
	related []interfaces.Relatable
}

func NewInterval(chrom string, start uint32, end uint32, fields [][]byte, source uint32, related []interfaces.Relatable) *Interval {
	return &Interval{chrom: chrom, start: start, end: end, Fields: fields, source: source, related: related}
}

func (i *Interval) Chrom() string                   { return i.chrom }
func (i *Interval) Start() uint32                   { return i.start }
func (i *Interval) End() uint32                     { return i.end }
func (i *Interval) Related() []interfaces.Relatable { return i.related }
func (i *Interval) AddRelated(b interfaces.Relatable) {
	i.related = append(i.related, b)
}

func (i *Interval) Source() uint32       { return i.source }
func (i *Interval) SetSource(src uint32) { i.source = src }

func (i *Interval) String() string {
	return string(bytes.Join(i.Fields, []byte{'\t'}))
}

func unsafeString(b []byte) string {
	return *(*string)(unsafe.Pointer(&b))
}

func IntervalFromBedLine(line []byte) (interfaces.Relatable, error) {
	line = bytes.TrimRight(line, "\r\n")
	fields := bytes.Split([]byte(string(line)), []byte{'\t'})
	start, err := strconv.ParseUint(unsafeString(fields[1]), 10, 32)
	if err != nil {
		return nil, err
	}
	end, err := strconv.ParseUint(unsafeString(fields[2]), 10, 32)
	if err != nil {
		return nil, err
	}
	i := Interval{chrom: string(fields[0]), start: uint32(start), end: uint32(end), related: nil, Fields: fields}
	return &i, nil
}

type RefAltInterval struct {
	Interval
	refalt [2]int
	HasEnd bool
}

func (i *RefAltInterval) SetRefAlt(ra []int) {
	i.refalt[0] = ra[0]
	i.refalt[1] = ra[1]
}

func (i *RefAltInterval) Ref() string {
	return string(i.Fields[i.refalt[0]])
}

func (i *RefAltInterval) Alt() []string {
	f := string(i.Fields[i.refalt[1]])
	return strings.Split(f, ",")
}

func (i *RefAltInterval) End() uint32 {
	if i.HasEnd {
		return i.Interval.End()
	}
	return i.Start() + uint32(len(i.Ref()))
}

var _ interfaces.IRefAlt = (*RefAltInterval)(nil)