func (g *SeedIndex) AddSequence(seq *SeedSequence) {
	maxSeed := 0
	for i := 1; i < len(seq.segments); i += 2 {
		seed := seq.segments[i]
		if seed > maxSeed {
			maxSeed = seed
		}
	}
	seedSet := util.NewIntSetCapacity(maxSeed + 1)
	for i := 1; i < len(seq.segments); i += 2 {
		seed := seq.segments[i]
		seedSet.Add(uint(seed))
	}
	g.lock.Lock()
	g.sequences = append(g.sequences, seq)
	g.seedSets = append(g.seedSets, seedSet)
	g.lock.Unlock()
}
/*func (g *SeedIndex) Contains(kmer uint) bool {
return g.kmers[kmer]
}
package seeds
import (
	"fmt"
	"github.com/jteutenberg/downpore/sequence"
	"github.com/jteutenberg/downpore/util"
	"sync"
)
type SeedIndex struct {
	seedSize     uint
	kmers        []bool           
	sequences    []*SeedSequence  
	sequenceSets []*util.IntSet   
	seedSets     []*util.IntSet   
	kmerMap      []int32          
	seedMap      []int            
	size         int
	lock         *sync.Mutex
}
func NewSeedIndex(k uint) *SeedIndex {
	size := 1
	for j := k; j > 0; j-- {
		size *= 4
	}
	var lock sync.Mutex
	sg := SeedIndex{kmers: make([]bool, size), kmerMap: make([]int32, size), seedSize: k, sequences: make([]*SeedSequence, 0, 100000), sequenceSets: make([]*util.IntSet, 0, 100000), seedSets: make([]*util.IntSet, 0, 100000), size: 0, lock: &lock}
	return &sg
}
func (g *SeedIndex) NewSeedSequence(seq sequence.Sequence) *SeedSequence {
	k := int(g.seedSize)
	var mask int
	for i := 0; i < k; i++ {
		mask = (mask << 2) | 3
	}
	count := seq.CountKmers(seq.Len(), k, mask, g.kmers)
	segments := make([]int, count*2+1)
	seq.WriteSegments(segments, k, mask, g.kmers)
	for i := 1; i < len(segments); i += 2 {
		segments[i] = int(g.kmerMap[segments[i]])
	}
	name := seq.GetName()
	seedSeq := SeedSequence{segments: segments, length: seq.Len(), id: seq.GetID(), name: &name, offset: seq.GetOffset(), inset: seq.GetInset(), rc: false}
	return &seedSeq
}
func (g *SeedIndex) SeedString(seed int) string {
	return sequence.KmerString(g.seedMap[seed], int(g.seedSize))
}
func (g *SeedIndex) SeedCount(seed int) uint {
	return g.sequenceSets[seed].Size()
}
func (g *SeedIndex) AddSeeds(seq sequence.Sequence, minSeeds int, kmerRanks []float64) {
	k := int(g.seedSize)
	var mask int
	for i := 0; i < k; i++ {
		mask = (mask << 2) | 3
	}
	count := seq.CountKmers(minSeeds, k, mask, g.kmers)
	q := seq.Quality()
	count = 0  
	if count < minSeeds {
		topN := make([]uint, minSeeds-count, minSeeds-count)
		topNValues := make([]float64, minSeeds-count, minSeeds-count)
		for i := 0; i < len(topNValues); i++ {
			topNValues[i] = 0
		}
		kmer := seq.KmerAt(0, k)
		nextIndex := k
		for nextIndex < seq.Len()-k {
			reset := false
			bestValue := 0.0
			var bestSeed int
			for i := 0; nextIndex < seq.Len() && i < k; i++ {
				kmer = seq.NextKmer(kmer, mask, nextIndex)
				nextIndex++
				if g.kmers[kmer] {
					reset = true
					break
				}
				value := kmerRanks[kmer]
				if q != nil {
					value *= float64(q[nextIndex-k/2])
				}
				if value > bestValue {
					bestValue = value
					bestSeed = kmer
				}
			}
			if !reset {
				n := 0
				for ; n < len(topNValues) && topNValues[n] < bestValue; n++ {
					if n > 0 {
						topNValues[n-1] = topNValues[n]
						topN[n-1] = topN[n]
					}
				}
				if n > 0 {
					topNValues[n-1] = bestValue
					topN[n-1] = uint(bestSeed)
				}
			}
			nextIndex += k
			if nextIndex < seq.Len()-k {
				kmer = seq.KmerAt(nextIndex, k)
			}
			nextIndex += k
		}
		g.lock.Lock()
		for _, kmer := range topN {
			if !g.kmers[kmer] {
				g.kmers[kmer] = true
				g.kmerMap[kmer] = int32(g.size)
				for len(g.sequenceSets) <= g.size {
					g.sequenceSets = append(g.sequenceSets, util.NewIntSet())
					g.seedMap = append(g.seedMap, -1)
				}
				g.seedMap[g.size] = int(kmer)
				g.size++
			}
			kmer = ReverseComplement(kmer, g.seedSize)
			if !g.kmers[kmer] {
				g.kmers[kmer] = true
				g.kmerMap[kmer] = int32(g.size)
				for len(g.sequenceSets) <= g.size {
					g.sequenceSets = append(g.sequenceSets, util.NewIntSet())
					g.seedMap = append(g.seedMap, -1)
				}
				g.seedMap[g.size] = int(kmer)
				g.size++
			}
		}
		g.lock.Unlock()
	}
}
func (g *SeedIndex) AddSingleSeeds(seq sequence.Sequence, seedRate int, ranks []float64) {
	k := int(g.seedSize)
	var mask int
	for i := 0; i < k; i++ {
		mask = (mask << 2) | 3
	}
	for i := 0; i < seq.Len()-seedRate; i += seedRate {
		count := seq.CountKmersBetween(i, i+seedRate, 1, k, mask, g.kmers)
		if count == 0 {
			end := i + seedRate
			kmer := seq.KmerAt(i, k)
			bestValue := ranks[kmer]
			bestKmer := kmer
			for j := i + k; j < end; j++ {
				kmer = seq.NextKmer(kmer, mask, j)
				value := ranks[kmer]
				if value > bestValue {
					bestValue = value
					bestKmer = kmer
				}
			}
			g.lock.Lock()
			if !g.kmers[bestKmer] {  
				g.kmers[bestKmer] = true
				g.kmerMap[bestKmer] = int32(g.size)
				for len(g.sequenceSets) <= g.size {
					g.sequenceSets = append(g.sequenceSets, util.NewIntSet())
					g.seedMap = append(g.seedMap, -1)
				}
				g.seedMap[g.size] = bestKmer
				g.size++
			}
			g.lock.Unlock()
		}
	}
}
func (g *SeedIndex) NewAllSeedSequence(seq sequence.Sequence) *SeedSequence {
	k := int(g.seedSize)
	var mask int
	for i := 0; i < k; i++ {
		mask = (mask << 2) | 3
	}
	segments := make([]int, 0, seq.Len()*2)
	prev := 0
	kmer := seq.KmerAt(0, k) >> 2
	kmerIndex := 0
	g.lock.Lock()
	for i := k - 1; i < seq.Len(); i++ {
		kmer = seq.NextKmer(kmer, mask, i)
		if !g.kmers[kmer] {
			g.kmers[kmer] = true
			g.kmerMap[kmer] = int32(g.size)
			for len(g.sequenceSets) <= g.size {
				g.sequenceSets = append(g.sequenceSets, util.NewIntSet())
				g.seedMap = append(g.seedMap, -1)
			}
			g.seedMap[g.size] = kmer
			g.size++
		}
		segments = append(segments, kmerIndex-prev)
		segments = append(segments, int(g.kmerMap[kmer]))
		prev = kmerIndex + k
		kmerIndex++
	}
	g.lock.Unlock()
	segments = append(segments, 0)
	name := seq.GetName()
	seedSeq := SeedSequence{segments: segments, length: seq.Len(), id: seq.GetID(), name: &name, offset: seq.GetOffset(), inset: seq.GetInset(), rc: false}
	return &seedSeq
}
func (g *SeedIndex) Size() int {
	return g.size
}
func (g *SeedIndex) GetSeedSequence(index uint) *SeedSequence {
	return g.sequences[index]
}
func (g *SeedIndex) GetSeedsFromKmers(kmers []uint16, seedSet *util.IntSet) {
	for _, k := range kmers {
		if g.kmers[k] {
			seedSet.Add(uint(g.kmerMap[k]))
		}
	}
}
func (g *SeedIndex) GetSeedSet(index uint) *util.IntSet {
	return g.seedSets[index]
}
func (g *SeedIndex) GetSeedLength() uint {
	return g.seedSize
}
func (g *SeedIndex) GetNumSequences() uint {
	return uint(len(g.sequences))
}