Example #1
0
// Map routines to iterate a function over an array, potentially splitting the array slice into
// chunks so that each chunk is processed concurrently. When using concurrent processing the
// Chunk size is either the nearest even division of the total array over the chosen concurrent
// processing goroutines or a specified maximum chunk size, whichever is smaller. Reducing
// chunk size can reduce the impact of divergence in time for processing chunks, but may add
// to overhead.
func Map(set Mapper, threads, maxChunkSize int) (results []interface{}, err error) {
	queue := make(chan Operator, 1)
	p := NewProcessor(queue, 0, threads)
	defer p.Stop()

	chunkSize := util.Min(int(math.Ceil(float64(set.Len())/float64(threads))), maxChunkSize)

	quit := make(chan struct{})

	go func() {
		for s := 0; s*chunkSize < set.Len(); s++ {
			select {
			case <-quit:
				break
			default:
				endChunk := util.Min(chunkSize*(s+1), set.Len())
				queue <- set.Slice(chunkSize*s, endChunk)
			}
		}
	}()

	for r := 0; r*chunkSize < set.Len(); r++ {
		result := <-p.out
		if result.Err != nil {
			err = bio.NewError("Map failed", 0, err)
			close(quit)
			break
		}
		results = append(results, result.Value)
	}

	return
}
Example #2
0
// 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
}
Example #3
0
func processServer(index interval.Tree, queue, output chan *feat.Feature, wg *sync.WaitGroup) {
	defer wg.Done()
	var (
		buffer      []byte   = make([]byte, 0, annotationLength)
		annotations Matches  = make(Matches, 0, maxAnnotations+1)
		o           *Overlap = &Overlap{&annotations}
		prefix      string   = ` ; Annot "`
		blank       string   = prefix + strings.Repeat("-", mapLength)
		overlap     int
	)

	for feature := range queue {
		annotations = annotations[:0]
		heap.Init(&Overlap{&annotations})
		buffer = buffer[:0]
		buffer = append(buffer, []byte(blank)...)
		if query, err := interval.New(string(feature.Location), feature.Start, feature.End, 0, nil); err != nil {
			fmt.Fprintf(os.Stderr, "Feature has end < start: %v\n", feature)
			continue
		} else {
			overlap = int(float64(feature.Len()) * minOverlap)
			if results := index.Intersect(query, overlap); results != nil {
				for hit := range results {
					o.Push(Match{
						Interval: hit,
						Overlap:  util.Min(hit.End(), query.End()) - util.Max(hit.Start(), query.Start()),
						Strand:   feature.Strand,
					})
					if len(annotations) > maxAnnotations {
						o.Pop()
					}
				}
			}
		}
		if len(annotations) > 0 {
			sort.Sort(&Start{&annotations})
			buffer = makeAnnotation(feature, annotations, len(prefix), buffer)
		}

		buffer = append(buffer, '"')
		feature.Attributes += string(buffer)
		output <- feature
	}
}
Example #4
0
func makeAnnotation(feature *feat.Feature, annotations Matches, prefixLen int, buffer []byte) []byte {
	var (
		annot                                []byte = buffer[prefixLen:]
		repRecord                            RepeatRecord
		repLocation                          *interval.Interval
		start, end, length                   int
		repStart, repEnd, repLeft, repLength int
		leftMargin, rightMargin              float64
		leftEnd, rightEnd                    bool
		mapStart, mapEnd                     int
		fullRepLength, repMissing            int
		i                                    int
		cLower, cUpper                       byte
		p                                    string
	)

	length = feature.Len()

	for annotIndex, repeat := range annotations {
		repRecord = repeat.Interval.Meta.(RepeatRecord)
		repLocation = repeat.Interval
		start = util.Max(repLocation.Start(), feature.Start)
		end = util.Min(repLocation.End(), feature.End)

		if repStart = repRecord.Start; repStart != -1 {
			repEnd = repRecord.End
			repLeft = repRecord.Left
			repLength = repStart + repLeft - 1
			if repLength <= 0 {
				repLength = 9999
			}

			if repLocation.Start() < feature.Start {
				repStart += feature.Start - repLocation.Start()
			}
			if repLocation.End() > feature.End {
				repEnd -= repLocation.End() - feature.End
			}

			leftMargin = float64(repStart) / float64(repLength)
			rightMargin = float64(repLeft) / float64(repLength)
			leftEnd = (leftMargin <= maxMargin)
			rightEnd = (rightMargin <= maxMargin)
		}

		mapStart = ((start - feature.Start) * mapLength) / length
		mapEnd = ((end - feature.Start) * mapLength) / length

		if feature.Strand == -1 {
			mapStart, mapEnd = mapLength-mapEnd-1, mapLength-mapStart-1
		}

		if mapStart < 0 || mapStart >= mapLength || mapEnd < 0 || mapEnd >= mapLength {
			fmt.Printf("mapStart: %d, mapEnd: %d, mapLength: %d\n", mapStart, mapEnd, mapLength)
			panic("MakeAnnot: failed to map")
		}

		cLower = 'a' + byte(annotIndex)
		cUpper = 'A' + byte(annotIndex)

		if leftEnd {
			annot[mapStart] = cUpper
		} else {
			annot[mapStart] = cLower
		}

		for i = mapStart + 1; i <= mapEnd-1; i++ {
			annot[i] = cLower
		}

		if rightEnd {
			annot[mapEnd] = cUpper
		} else {
			annot[mapEnd] = cLower
		}

		buffer = append(buffer, ' ')
		buffer = append(buffer, []byte(repRecord.Name)...)

		if repRecord.Start >= 0 {
			fullRepLength = repRecord.End + repLeft
			repMissing = repRecord.Start + repLeft
			if feature.Start > repLocation.Start() {
				repMissing += feature.Start - repLocation.Start()
			}
			if repLocation.End() > feature.End {
				repMissing += repLocation.End() - feature.End
			}
			p = fmt.Sprintf("(%.0f%%)", ((float64(fullRepLength)-float64(repMissing))*100)/float64(fullRepLength))
			buffer = append(buffer, []byte(p)...)
		}
	}

	return buffer
}