// 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 }