Пример #1
0
// calcInChunck does calculation in a chunck of SNPs.
func (cmd *cmdCt) calcInChunck(snpChan chan *pileup.SNP) *calc.Calculator {
	// Create job channel.
	// Each job is a array of SNPs, which we will calculate
	// correlations of the first SNP with the rest ones.
	jobChan := make(chan []*pileup.SNP)
	go func() {
		defer close(jobChan)
		arr := []*pileup.SNP{}
		for s := range snpChan {
			arr = append(arr, s)
			lag := s.Pos - arr[0].Pos

			if lag < 0 {
				cmd.panic("SNPs are not in order.")
			}

			if lag >= cmd.maxl {
				jobChan <- arr
				arr = arr[1:]
			}
		}
		jobChan <- arr
	}()

	// Make ncpu workers.
	// For each worker, do the calculation,
	// and push the result into a channel.
	ncpu := runtime.GOMAXPROCS(0)
	c := make(chan *calc.Calculator)
	for i := 0; i < ncpu; i++ {
		go func() {
			covs := calc.New(cmd.maxl)
			maxN := 10000
			xArr := make([]float64, maxN)
			yArr := make([]float64, maxN)
			for arr := range jobChan {
				cmd.calcSNPArr(arr, covs, xArr, yArr)
			}
			c <- covs
		}()
	}

	// Wait for all the worker,
	// and collect their results.
	var covs *calc.Calculator
	for i := 0; i < ncpu; i++ {
		cc := <-c
		if i == 0 {
			covs = cc
		} else {
			covs.Append(cc)
		}
	}

	return covs
}