Skip to content

Commit

Permalink
removing plotCov option - and with it a bunch of dependencies - so th…
Browse files Browse the repository at this point in the history
…at groot can get back into conda. Also bumps version patch
  • Loading branch information
will-rowe committed Apr 24, 2020
1 parent 242ba69 commit fffdefa
Show file tree
Hide file tree
Showing 8 changed files with 24 additions and 87 deletions.
16 changes: 1 addition & 15 deletions cmd/report.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
package cmd

import (
"errors"
"fmt"
"log"
"os"
Expand All @@ -37,7 +36,6 @@ import (
var (
bamFile *string // a BAM file to generate report from
covCutoff *float64 // breadth of coverage theshold
plotCov *bool // keeps the coverage plots for each annotated gene
lowCov *bool // reports ARGs which don't have 5' or 3' coverage
)

Expand All @@ -49,9 +47,7 @@ var reportCmd = &cobra.Command{
This will report gene, read count, gene length, coverage cigar to STDOUT as tab separated values.
Coverage cigar is present to help debug and indicates if the reference gene is covered (M) or not (D).
This command also prints a coverage plot for each gene (--plotCov flag)`,
Coverage cigar is present to help debug and indicates if the reference gene is covered (M) or not (D).`,
Run: func(cmd *cobra.Command, args []string) {
runReport()
},
Expand All @@ -64,7 +60,6 @@ func init() {
RootCmd.AddCommand(reportCmd)
bamFile = reportCmd.Flags().String("bamFile", "", "BAM file generated by groot alignment (will use STDIN if not provided)")
covCutoff = reportCmd.Flags().Float64P("covCutoff", "c", 0.97, "coverage cutoff for reporting ARGs")
plotCov = reportCmd.Flags().Bool("plotCov", false, "plots coverage of each reported ARG (saves to ./groot-plots/)")
lowCov = reportCmd.Flags().Bool("lowCov", false, "reports ARGs which don't have 5' or 3' coverage (overrides -c option)")
}

Expand Down Expand Up @@ -118,15 +113,6 @@ func runReport() {
log.Printf("\tcoverage cutoff: %.2f", *covCutoff)
log.Printf("\tprocessors: %d", *proc)
bamReader := reporting.NewBAMreader()
if *plotCov == true {
bamReader.Plot = true
// setup the plot dir
if _, err := os.Stat("./groot-plots"); os.IsNotExist(err) {
if err := os.MkdirAll("./groot-plots", 0700); err != nil {
log.Fatal(errors.New("can't create a ./groot-plots directory"))
}
}
}
if *bamFile != "" {
bamReader.InputFile = *bamFile
}
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
# The short X.Y version
version = '1.0'
# The full version, including alpha/beta/rc tags
release = '1.0.0'
release = '1.0.2'


# -- General configuration ---------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ ls *.bam | parallel --gnu "groot report --bamFile {} -c 1 --plotCov > {/.}.repor
- `-c 1` tells groot to only report ARGs that have been entirely covered by reads, I.E. a full-length,100% identity match
- `--plotCov` tells groot to generate coverage plots for each ARG it reports

> NOTE: `--plotCov` was removed after v.1.0.0 as it relied on a library that could not be packaged for conda. Hopefully I can add it back in soon.
We have now generated a resistome profile for each sample, using only full-length ARG sequences (present in the ARG-ANNOT database). We can sum rural/urban resistome profiles with a little bash loop to combine reports:

```bash
Expand Down
1 change: 0 additions & 1 deletion docs/using-groot.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,3 @@ Flags explained:
Some more flags that can be used:

- `--lowCov`: overrides `c` option and will report ARGs which may not be covered at the 5'/3' ends
- `--plotCov`: outputs coverage plot for each ARG reported
2 changes: 0 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module github.com/will-rowe/groot
go 1.14

require (
github.com/adam-hanna/arrayOperations v0.2.6
github.com/biogo/biogo v1.0.2
github.com/biogo/hts v1.1.0
github.com/dgryski/go-minhash v0.0.0-20190315135803-ad340ca03076 // indirect
Expand All @@ -15,5 +14,4 @@ require (
github.com/spf13/pflag v1.0.5
github.com/will-rowe/gfa v0.0.0-20190502084819-05c93955478b
github.com/will-rowe/ntHash v0.0.0-20190624153018-541592fc7931
gonum.org/v1/plot v0.7.0
)
20 changes: 0 additions & 20 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/adam-hanna/arrayOperations v0.2.6 h1:QZC99xC8MgUawXnav7bFMejs/dm7YySnDpMx3oZzz2Y=
github.com/adam-hanna/arrayOperations v0.2.6/go.mod h1:iIzkSjP91FnE66cUFNAjjUJVmjyAwCH0SXnWsx2nbdk=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjjBW6xcqyQA/j5e0D6GytH95g0gQ=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
Expand Down Expand Up @@ -35,8 +31,6 @@ github.com/dgryski/go-minhash v0.0.0-20190315135803-ad340ca03076/go.mod h1:VBi0X
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/ekzhu/lshensemble v1.1.0 h1:qxuckiF7m1ARGe8zxyqmzWFgpNVAsORbatF5XIj/oYc=
github.com/ekzhu/lshensemble v1.1.0/go.mod h1:9O+7M8zbVXy2WMyTT0zgia+rsQXrX0gB9CihuFwwRK8=
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
Expand All @@ -46,8 +40,6 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
Expand All @@ -69,12 +61,9 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmg
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5 h1:PJr+ZMXIecYc1Ey2zucXdR73SMBtgjPgwa31099IMv0=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -139,13 +128,9 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
Expand Down Expand Up @@ -173,15 +158,11 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/plot v0.7.0 h1:Otpxyvra6Ie07ft50OX5BrCfS/BWEMvhsCUHwPEJmLI=
gonum.org/v1/plot v0.7.0/go.mod h1:2wtU6YrrdQAhAF9+MTd5tOQjrov/zF70b1i99Npjvgo=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
Expand All @@ -201,4 +182,3 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
64 changes: 18 additions & 46 deletions src/reporting/reporting.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,30 +6,22 @@ import (
"log"
"os"
"strconv"
"strings"
"sync"

"github.com/biogo/hts/bam"
"github.com/biogo/hts/bgzf"
"github.com/biogo/hts/sam"

"gonum.org/v1/plot"
"gonum.org/v1/plot/plotter"
"gonum.org/v1/plot/plotutil"
"gonum.org/v1/plot/vg"
)

type annotation struct {
arg string
count int
length int
coverage plotter.XYs
cigar string
arg string
count int
length int
cigar string
}

type BAMreader struct {
InputFile string
Plot bool
CoverageCutoff float64
LowCov bool
}
Expand Down Expand Up @@ -102,20 +94,25 @@ func (proc *BAMreader) Run() {
wg.Add(1)
go func(recs []*sam.Record, ref *sam.Reference, sendChan chan<- annotation) {
defer wg.Done()

// coverageCheck tells us if all bases in the reference have been covered by a read
coverageCheck := make(map[int]struct{})

// pileup contains coverage value for each base in the reference
pileup := make([]int, ref.Len())

// for each record, move along the alignment and update reference coverage info
for _, rec := range recs {
recStart := rec.Start()
recEnd := recStart + rec.Len()

// if the read goes beyond the reference, only go up to the last base of the ref
if recEnd > len(pileup)-1 {
recEnd = len(pileup) - 1
}

for i := recStart; i <= recEnd; i++ {

// if this is the first time the base has been covered, update coverageCheck
if _, ok := coverageCheck[i]; !ok {
coverageCheck[i] = struct{}{}
Expand All @@ -128,19 +125,19 @@ func (proc *BAMreader) Run() {
// check we have a fully covered reference
pileupCoverage := float64(len(coverageCheck)) / float64(len(pileup))
if pileupCoverage >= proc.CoverageCutoff {

// get the reference name (remove asterisk from cluster representative if it is present)
refName := ref.Name()
if refName[0] == 42 {
refName = refName[1:]
}

// represent pileup as a CIGAR-ish string (so can see what bases aren't covered)
cigar := []string{}

// plot coverage for this gene using the pileup
coverage := make(plotter.XYs, len(pileup))
for i := range coverage {
coverage[i].X = float64(i)
coverage[i].Y = float64(pileup[i])
if pileup[i] == 0 {
for _, val := range pileup {
if val == 0 {
cigar = append(cigar, "D")
} else {
cigar = append(cigar, "M")
Expand All @@ -152,11 +149,10 @@ func (proc *BAMreader) Run() {
}
// create the annotation
anno := annotation{
arg: refName,
count: len(records),
length: ref.Len(),
coverage: coverage,
cigar: cleanCigar,
arg: refName,
count: len(records),
length: ref.Len(),
cigar: cleanCigar,
}
// send annotation on
sendChan <- anno
Expand All @@ -173,30 +169,6 @@ func (proc *BAMreader) Run() {
for anno := range reportChan {
// print info to stdout
fmt.Printf("%v\t%d\t%d\t%v\n", anno.arg, anno.count, anno.length, anno.cigar)

// this will clean up the ARG name so that we can use it as a filename
var replacer = strings.NewReplacer("/", "__", "\t", "__")

// plot coverage for this gene
if proc.Plot == true {
covPlot, err := plot.New()
if err != nil {
panic(err)
}
covPlot.Title.Text = "coverage plot"
covPlot.X.Label.Text = "position in gene"
covPlot.Y.Label.Text = "coverage (number of reads at position)"
err = plotutil.AddLinePoints(covPlot, anno.arg, anno.coverage)
if err != nil {
panic(err)
}
// clean the ARG name
anno.arg = replacer.Replace(anno.arg)
fileName := fmt.Sprintf("./groot-plots/coverage-for-%v.png", anno.arg)
if err := covPlot.Save(8*vg.Inch, 8*vg.Inch, fileName); err != nil {
panic(err)
}
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ const major = 1
const minor = 0

// patch is the patch version number
const patch = 1
const patch = 2

// GetVersion() returns the full version string for the current GROOT software
// GetVersion returns the full version string for the current GROOT software
func GetVersion() string {
return fmt.Sprintf("%d.%d.%d", major, minor, patch)
}
Expand Down

0 comments on commit fffdefa

Please sign in to comment.