
# Coverage in regions

Maybe more important than the total number of reads is the coverage information: at what read count is each base (genome-wide or within a target set) covered? For germline calls we need a minimum of ~13X to call heterozygous variants reliably; this number goes up for tumor samples due to purity and clonality confounders. 

If no target region was given we calculate these metrics for a list of 'medically actionable genes' based on the [Personalis ACE Clinical Exome](http://www.personalis.com/clinical/).

```{r total-coverage-load}
get_quantile_cov = function(path){
    cov_tab = data.frame()
    cov_regions = data.frame()
    for (fn in list.files(path, pattern = "_coverage.bed", full.names = TRUE)){
            d = read.table(fn, header=T, sep="\t", comment.char = "%")
            for (i in c("cutoff10", "cutoff20", "cutoff50")){
                # q = quantile(d[,i],c(.10,.25,.50,.75,.90))
                q = quantile(d[,i],c(0.01,.10,.25,.50,.75,.90,.99))
                labels=factor(rev(names(q)),levels=c("1%","10%","25%","50%","75%","90%","99%"))

                s = gsub("-ready","",d[1,"sample"])
                t = data.frame(quantiles=q*100, type=labels, sample=s, min_reads=i)
                cov_tab = rbind(cov_tab, t)
                
                
            }
            ma = (d %>% dplyr::select(cutoff10, cutoff20, cutoff50)) > 0.60
            if (nrow(cov_regions) == 0){
              cov_regions = ma
            }else{
              cov_regions = cov_regions + ma
            }    

    }
    row.names(cov_regions) = as.character(d$region)
    list("sample" = cov_tab, "region" = as.data.frame(cov_regions))
}


get_total_cov = function(path){
    cov_tab = data.frame()
    for (fn in list.files(path, pattern = "_cov_total.tsv", full.names = TRUE)){
            d = read.table(fn, header=F, sep="\t")
            d = d[order(d[,1]),]
            print(head(d,30))
            pct = rev(cumsum(rev(d[,2]))/sum(d[,2]) * 100)
            s = gsub("-ready","",d[1,4])
            t = data.frame(depth=d[,1], bases=pct, sample=s)
            cov_tab = rbind(cov_tab, t)
    }
    cov_tab
}

make_total_cov_plots = function(cov_tab){
    p =ggplot(cov_tab, aes(y=bases, x=depth, group=sample)) +
        geom_line(size=2, alpha=.5)+
        theme_bw()+
        labs(list(y="% of bed file > depth", x="# of reads"))
    print(p)
}

make_quantile_plots = function(cov_tab){
    p1 = ggplot(cov_tab %>% filter(min_reads=='cutoff10'), aes(x=type, y=quantiles,  group=sample)) +
    geom_line(size=2, alpha=.5)+
    theme_bw()+
    labs(list(x="% of target regions with\nmore than X bases covered", y="% of nt covered\ninside the target", title="considered covered when nt has >10 reads"))

    p2 = ggplot(cov_tab %>% filter(min_reads=='cutoff20'), aes(x=type, y=quantiles,  group=sample)) +
    geom_line(size=2, alpha=.5)+
    theme_bw()+
    labs(list(x="% of target regions with\nmore than X bases covered", y="% of nt covered\ninside the target", title="considered covered when nt has >25 reads"))

    p3 = ggplot(cov_tab %>% filter(min_reads=='cutoff50'), aes(x=type, y=quantiles, group=sample)) +
    geom_line(size=2, alpha=.5)+
    theme_bw()+
    labs(list(x="% of target regions with\nmore than X bases covered", y="% of nt covered\ninside the target", title="considered covered when nt has >50 reads"))

    grid.arrange(p1, p2, p3, ncol=1)
}

make_quantile_region_plots = function(dd, n_samples){
    # cov_tab = melt(cov_tab, id.vars="region")
    
    p1 = ggplot(dd %>% group_by(cutoff10) %>% summarise(n_regions = n())  %>% filter(q10<n_samples*0.8), aes(x=n_regions, y=q10)) +
    geom_point(size=2, alpha=.5)+
    theme_bw()+
    labs(list(x="number of regions", y="num of samples with region covered", title="considered covered when nt has >10 reads. Only looking at regions with < 80% of samples"))

    p2 = ggplot(dd %>% group_by(cutoff20) %>% summarise(n_regions = n())  %>% filter(q20<n_samples*0.8), aes(x=n_regions, y=q20)) +
    geom_point(size=2, alpha=.5)+
    theme_bw()+
    labs(list(x="number of regions", y="num of samples with region covered", title="considered covered when nt has >20 reads. Only looking at regions with < 80% of samples"))

    p3 = ggplot(dd %>% group_by(cutoff50) %>% summarise(n_regions = n())  %>% filter(q50<n_samples*0.8), aes(x=n_regions, y=q50)) +
    geom_point(size=2, alpha=.5)+
    theme_bw()+
    labs(list(x="number of regions", y="num of samples with region covered", title="considered covered when nt has >50 reads. Only looking at regions with < 80% of samples"))

    grid.arrange(p1, p2, p3, ncol=1)
}
```

### Total coverage by sample

```{r cov-total-fig, fig.height=6, fig.width=11, cache=TRUE}
n_samples = nrow(qc)
cov_tab_total = get_total_cov(file.path(path_results, "coverage"))
make_total_cov_plots(cov_tab_total)
```

### Completeness by sample

A more detailed look at the previous plot. For three different cutoffs (at least 10, 25 or 50 reads) check what percentage of target _regions_ are covered with at least that many reads on average (X-axis), and ...

```{r completeness-fig, fig.height=12, fig.width=12, cache=TRUE}
cov_tab = get_quantile_cov(file.path(path_results, "coverage"))
make_quantile_plots(cov_tab$sample)
```

Flagging samples that are problematic. i.e., where more than 90% of target regions have less than 60% covered at completeness cut-off of 10.

```{r table-completeness, results='asis'}
kable(cov_tab$sample %>% filter(type == "90%") %>%
          spread(min_reads, quantiles) %>%
          dplyr::select(targets_pct=type, sample, min_10=cutoff10, min_20=cutoff20, min_50=cutoff50) %>%
          dplyr::filter(min_10<60),
      align="c", digits=2)

```

### Completeness by region

```{r completeness-region-fig, fig.height=12, fig.width=12, cache=TRUE}
make_quantile_region_plots(cov_tab$region, n_samples)
```

Regions where less than 60% of samples covered at completeness cut-off of 10.

```{r table-completeness-regions, results='asis'}
n_samples = nrow(qc)
kable(head(cov_tab$region %>% mutate(region=row.names(cov_tab$region)) %>% 
      dplyr::select(region, cutoff10, cutoff20, cutoff50) %>% filter(cutoff10 < n_samples*0.6),50), 
      align="c", digits=2)
write.table(cov_tab$region, file.path(path_results, "completeness_by_region_and_sample.tsv"))
```



```{r cov-uniformity-load, echo=FALSE, eval=FALSE}
## Coverage uniformity

cov_tab = data.frame()

get_bias_cov = function(path){
    for (fn in list.files(path, pattern = "_cov.tsv", full.names = TRUE)){
            d = read.table(fn, header=T, sep="\t")

            cv = d[,"std"]/d[,"mean"]
            bias = (d[,"ntdow"] + d[,"ntup"])/d[,"size"] * 100
            s = as.character(gsub("-ready","",d[1,"sample"]))
            t = data.frame(bias=bias, cv=cv, mean=d[,"mean"], sample=s)
            cov_tab = rbind(cov_tab, t)


    }
    cov_tab
}

make_bias_plot = function(cov_tab){
    p1 = ggplot(cov_tab, aes(x=log2(mean), y=cv)) +
    geom_point(alpha=0.5) +
    scale_color_brewer(palette = "Set1") +
    labs(list(y="coefficient of variation",x="log2(mean coverage)")) +
    theme_bw() +
        ggtitle("coverage variation for each target region")

    p2 = ggplot(cov_tab, aes( x=sample,y=bias)) +
    geom_jitter(alpha=0.5) +
    scale_color_brewer(palette = "Set1") +
    theme_bw() +
    theme(axis.text.x = element_text(angle = 90, hjust = 1)) +
    labs(list(y="% of nt with mean-2SD > coverage > mean+2SD ")) +
        ggtitle("% of nucleotides with extreme\ncoverage inside target regions")
    # grid.arrange(p1, p2, ncol=1)
    print(p2)
}
```

```{r cov-uniformity-fig, fig.height=12, fig.width=12, cache=TRUE, eval=FALSE, echo=FALSE}
bias_tab = get_bias_cov(file.path(path_results,"bias"))
make_bias_plot(bias_tab)
```

