func (s *S) TestKmerKmerUtilities(c *check.C) { for k := MinKmerLen; k <= 8; k++ { // again not testing all exhaustively for kmer := Kmer(0); uint(kmer) <= util.Pow4(k)-1; kmer++ { // Interconversion between string and Kmer if rk, err := KmerOf(k, Stringify(k, kmer)); err != nil { c.Fatalf("Failed Kmer conversion: %v", err) } else { c.Check(rk, check.Equals, kmer) } // Complementation dc := ComplementOf(k, ComplementOf(k, kmer)) if dc != kmer { c.Logf("kmer: %s\ndouble complement: %s\n", Stringify(k, kmer), Stringify(k, dc)) } c.Check(dc, check.Equals, kmer) // GC content ks := Stringify(k, kmer) gc := 0 for _, b := range ks { if b == 'G' || b == 'C' { gc++ } } c.Check(GCof(k, kmer), check.Equals, float64(gc)/float64(k)) } } }
// Return an estimate of the amount of memory required for the filter. func (p *PALS) filterMemRequired(filterParams *filter.Params) uintptr { words := util.Pow4(filterParams.WordSize) tubeWidth := filterParams.TubeOffset + filterParams.MaxError maxActiveTubes := (p.target.Len()+tubeWidth-1)/filterParams.TubeOffset + 1 tubes := uintptr(maxActiveTubes) * unsafe.Sizeof(tubeState{}) finger := unsafe.Sizeof(uint32(0)) * uintptr(words) pos := unsafe.Sizeof(0) * uintptr(p.target.Len()) return finger + pos + tubes }
// Render the rainbow based on block of sequence in the index with the given size. // Vary specifies which color values change in response to kmer frequency. Setting desch to true // specifies using the ordering described in Deschavanne (1999). func (self *CGR) Paint(vary int, desch bool, block, size int) (i *image.RGBA, err error) { k := self.Index.GetK() kmask := util.Pow4(k) kmers := make([]uint, kmask) f := func(index *kmerindex.Index, _, kmer int) { kmers[kmer]++ } self.Index.ForEachKmerOf(self.Index.Seq, block*size, (block+1)*size-1, f) c := &color.HSVA{} max := util.UMax(kmers...) scale := 1 / float64(max) for kmer, v := range kmers { x, y := 0, 0 if desch { xdiff := 0 for i, km := k-1, kmer; i >= 0; i, km = i-1, km>>2 { xdiff = ((km & 2) >> 1) x += xdiff << uint(i) y += ((km & 1) ^ (xdiff ^ 1)) << uint(i) } } else { for i, km := k-1, kmer; i >= 0; i, km = i-1, km>>2 { x += (km & 1) << uint(i) y += (((km & 1) ^ ((km & 2) >> 1)) ^ 1) << uint(i) } } val := float64(v) * scale if vary&H != 0 { c.H = val * 240 } else { c.H = self.BackGround.H } if vary&S != 0 { c.S = val } else { c.S = self.BackGround.S } if vary&V != 0 { c.V = val } else { c.V = self.BackGround.V } if vary&A != 0 { c.A = val } else { c.A = self.BackGround.A } self.Set(x, y, c) } return self.RGBA, nil }
// Create a new Kmer Index with a word size k based on sequence func New(k int, sequence *seq.Seq) (i *Index, err error) { switch { case k > MaxKmerLen: return nil, bio.NewError("k greater than MaxKmerLen", 0, k, MaxKmerLen) case k < MinKmerLen: return nil, bio.NewError("k less than MinKmerLen", 0, k, MinKmerLen) case k+1 > sequence.Len(): return nil, bio.NewError("sequence shorter than k+1-mer length", 0, k+1, sequence.Len()) } i = &Index{ finger: make([]Kmer, util.Pow4(k)+1), // Need a Tn+1 finger position so that Tn can be recognised k: k, kMask: Kmer(util.Pow4(k) - 1), Seq: sequence, indexed: false, } i.buildKmerTable() return }
// Render the rainbow based on block of sequence in the index with the given size. Left and right define the extent of the rendering. // Vary specifies which color values change in response to kmer frequency. func (self *KmerRainbow) Paint(vary int, block, size, left, right int) (i *image.RGBA, err error) { right = util.Min(right, self.Rect.Dx()) kmers := make([]uint32, self.RGBA.Rect.Dy()) kmask := util.Pow4(self.Index.GetK()) kmaskf := float64(kmask) f := func(index *kmerindex.Index, _, kmer int) { kmers[int(float64(kmer)*float64(self.RGBA.Rect.Dy())/kmaskf)]++ } self.Index.ForEachKmerOf(self.Index.Seq, block*size, (block+1)*size-1, f) c := color.HSVA{} lf := float64(len(kmers)) / 360 var val float64 scale := 1 / float64(self.Max) for y, v := range kmers { val = float64(v) / scale c.H = float64(y) / lf if vary&S != 0 { c.S = val } else { c.S = self.BackGround.S } if vary&V != 0 { c.V = val } else { c.V = self.BackGround.V } if vary&A != 0 { c.A = val } else { c.A = self.BackGround.A } if left >= 0 && right > left { for x := left; x < right; x++ { self.Set(x, y, c) } } else { println(left, right) for x := 0; x < self.Rect.Dx(); x++ { self.Set(x, y, c) } } } return self.RGBA, nil }
// Create a new KmerRainbow defined by the rectangle r, kmerindex index and background color. func NewKmerRainbow(r image.Rectangle, index *kmerindex.Index, background color.HSVA) *KmerRainbow { // should generalise the BG color h := r.Dy() kmers := make([]int, h) kmask := util.Pow4(index.GetK()) kmaskf := float64(kmask) f := func(index *kmerindex.Index, _, kmer int) { kmers[int(float64(kmer)*float64(h)/kmaskf)]++ } index.ForEachKmerOf(index.Seq, 0, index.Seq.Len(), f) max := util.Max(kmers...) return &KmerRainbow{ RGBA: image.NewRGBA(r), Index: index, Max: max, BackGround: background, } }
// Make a new KmerColor initialising the Kmer length to k. func New(k int) (c *KmerColor) { return &KmerColor{ kmask: kmerindex.Kmer(util.Pow4(k) - 1), } }