func NewCoord(ref *sam.Reference, pos int, seq int32) biopb.Coord {
	a := biopb.Coord{RefId: int32(ref.ID()), Pos: int32(pos), Seq: seq}
	if a.RefId == biopb.InfinityRefID && pos < 0 {
		a.Pos = 0
	}
	return a
}
NewCoord generates biopb.Coord from the given parameters.
package bam
import (
	"context"
	"fmt"
	"math"
	"math/rand"
	"strings"
	"github.com/grailbio/base/backgroundcontext"
	"github.com/grailbio/base/file"
	"github.com/grailbio/base/log"
	"github.com/grailbio/bio/biopb"
	"github.com/grailbio/hts/bam"
	"github.com/grailbio/hts/bgzf"
	"github.com/grailbio/hts/sam"
)
var UniversalRange = biopb.CoordRange{
	Start: biopb.Coord{0, 0, 0},
	Limit: biopb.Coord{biopb.InfinityRefID, biopb.InfinityPos, 0},
}
var MappedRange = biopb.CoordRange{
	Start: biopb.Coord{0, 0, 0},
	Limit: biopb.Coord{biopb.LimitValidRefID, biopb.InfinityPos, 0},
}
type Shard struct {
	StartRef *sam.Reference
	EndRef   *sam.Reference
	Start    int
	End      int
	StartSeq int
	EndSeq   int
	Padding  int
	ShardIdx int
}
func UniversalShard(header *sam.Header) Shard {
	var startRef *sam.Reference
	if len(header.Refs()) > 0 {
		startRef = header.Refs()[0]
	}
	return Shard{
		StartRef: startRef,
		EndRef:   nil,
		Start:    0,
		End:      math.MaxInt32,
	}
}
func (s *Shard) PadStart(padding int) int {
	return max(0, s.Start-padding)
}
func (s *Shard) PaddedStart() int {
	return s.PadStart(s.Padding)
}
func (s *Shard) PadEnd(padding int) int {
	if s.End == 0 && s.EndSeq == 0 {
		return 0
	}
	if s.EndRef == nil {
		return min(math.MaxInt32, s.End+padding)
	}
	return min(s.EndRef.Len(), s.End+padding)
}
func (s *Shard) PaddedEnd() int {
	return s.PadEnd(s.Padding)
}
func (s *Shard) RecordInShard(r *sam.Record) bool {
	return s.CoordInShard(0, CoordFromSAMRecord(r, 0))
}
func (s *Shard) MateInShard(r *sam.Record) bool {
	return s.CoordInShard(0, MateCoordFromSAMRecord(r, 0))
}
func (s *Shard) RecordInPaddedShard(r *sam.Record) bool {
	return s.CoordInShard(s.Padding, CoordFromSAMRecord(r, 0))
}
func (s *Shard) RecordInStartPadding(r *sam.Record) bool {
	paddedStartCoord := NewCoord(s.StartRef, s.PaddedStart(), 0)
	startCoord := NewCoord(s.StartRef, s.Start, 0)
	coord := CoordFromSAMRecord(r, 0)
	return coord.GE(paddedStartCoord) && coord.LT(startCoord)
}
func (s *Shard) CoordInShard(padding int, coord biopb.Coord) bool {
	startCoord := NewCoord(s.StartRef, s.PadStart(padding), 0)
	if coord.LT(startCoord) {
		return false
	}
	endCoord := NewCoord(s.EndRef, s.PadEnd(padding), 0)
	return coord.LT(endCoord)
}
func (s *Shard) String() string {
	return fmt.Sprintf("%d:(%s[%d],%d(%d))-(%s[%d],%d(%d))",
		s.ShardIdx, s.StartRef.Name(), s.StartRef.ID(), s.Start, s.PaddedStart(),
		s.EndRef.Name(), s.EndRef.ID(), s.End, s.PaddedEnd())
}
func min(x, y int) int {
	if y < x {
		return y
	}
	return x
}
func max(x, y int) int {
	if y > x {
		return y
	}
	return x
}
func ShardToCoordRange(shard Shard) biopb.CoordRange {
	return biopb.CoordRange{
		biopb.Coord{RefId: int32(shard.StartRef.ID()), Pos: int32(shard.Start), Seq: int32(shard.StartSeq)},
		biopb.Coord{RefId: int32(shard.EndRef.ID()), Pos: int32(shard.End), Seq: int32(shard.EndSeq)},
	}
}
func CoordRangeToShard(header *sam.Header, r biopb.CoordRange, padding, shardIdx int) Shard {
	var startRef *sam.Reference
	if r.Start.RefId >= 0 {
		startRef = header.Refs()[r.Start.RefId]
	}
	var limitRef *sam.Reference
	var limitPos = int(r.Limit.Pos)
	if r.Limit.RefId >= 0 {
		if n := len(header.Refs()); int(r.Limit.RefId) < n {
			limitRef = header.Refs()[r.Limit.RefId]
			limitPos = int(r.Limit.Pos)
		} else {
			limitRef = header.Refs()[n-1]
			limitPos = limitRef.Len()
		}
	}
	return Shard{
		StartRef: startRef,
		Start:    int(r.Start.Pos),
		StartSeq: int(r.Start.Seq),
		EndRef:   limitRef,
		End:      limitPos,
		EndSeq:   int(r.Limit.Seq),
		Padding:  padding,
		ShardIdx: shardIdx,
	}
}
type CoordGenerator struct {
	LastRec biopb.Coord
}
func NewCoordGenerator() CoordGenerator {
	return CoordGenerator{biopb.Coord{RefId: 0, Pos: -1, Seq: 0}}
}
func (g *CoordGenerator) Generate(refID, pos int32) biopb.Coord {
	if refID == biopb.InfinityRefID {
		pos = 0
	}
	if refID < biopb.UnmappedRefID || pos < 0 {
		log.Panicf("Illegal addr: %v %v", refID, pos)
	}
	a := biopb.Coord{RefId: refID, Pos: pos, Seq: 0}
	p := biopb.Coord{RefId: g.LastRec.RefId, Pos: g.LastRec.Pos, Seq: 0}
	cmp := a.Compare(p)
	if cmp < 0 {
		log.Panicf("Record coordinate decreased from %+v to %v:%v", g.LastRec, refID, pos)
	}
	if cmp == 0 {
		g.LastRec.Seq++
	} else {
		g.LastRec = a
	}
	return g.LastRec
}
func (g *CoordGenerator) GenerateFromRecord(rec *sam.Record) biopb.Coord {
	return g.Generate(int32(rec.Ref.ID()), int32(rec.Pos))
}
func CoordFromSAMRecord(rec *sam.Record, seq int32) biopb.Coord {
	return NewCoord(rec.Ref, rec.Pos, seq)
}
func MateCoordFromSAMRecord(rec *sam.Record, seq int32) biopb.Coord {
	return NewCoord(rec.MateRef, rec.MatePos, seq)
}