%% \VignetteIndexEntry{B.4 Regulatory Variants: From BAM To Binding Motif}

\chapter{Regulatory Variants: BAM to Motif}

<<setup,echo=FALSE>>=
library(Morgan2013)
library(org.Hs.eg.db)
library(TxDb.Hsapiens.UCSC.hg19.knownGene)
library(BSgenome.Hsapiens.UCSC.hg19)
library(seqnames.db)
library(gmapR)
library(VariantTools)
library(lattice)
library(MotifDb)
library(parallel)
@ 

\section{Introduction}

This work flow was originally constructed by Paul Shannon and Valerie
Obenchain.

This portion of the lab represents a work flow from aligned reads
through variant calls to consequences for regulatory motif binding
sites. The work flow reproduces part of Huang \emph{et al}'s `Highly
recurrent TERT promoter mutations in human
melanoma'~\cite{huang2013highly}. Briefly, previous sequencing studies
identified mutations in the TERT promoter locus; Huang et al.\
validated these in additional cell lines, and noted that the mutation
introduced a binding site for the E-twenty-six transcription
factor. We reproduce some of these results, notably calling variants
in the TERT region across cell lines, and matching a data base of
binding motifs to the original and modified promoter regions.

If you are not using windows, load the \Rpackage{parallel} package
and set the number of cores to use to the number of cores on your
machine.
<<parallel>>=
library(parallel); options(mc.cores=detectCores())
@ 
%%
We'll use annotation resources for humans, specifically the
gene-centric \Biocannopkg{org.Hs.eg.db} for basic information about
TERT, the \Biocannopkg{TxDb.Hsapiens.UCSC.hg19.knownGene} package for
information about exon and transcript structure of TERT, and the
\Biocannopkg{BSgenome.Hsapiens.UCSC.hg19} package for sequence information.
<<annotation-libraries>>=
library(org.Hs.eg.db)
library(TxDb.Hsapiens.UCSC.hg19.knownGene)
library(BSgenome.Hsapiens.UCSC.hg19)
@ 
%% 
Huang \emph{et al} provide BAM files of reads aligning in the
neighborhood of TERT for several cell lines; a subset of these are
available for this lab. Create a variable \code{path} that points to
the directory containing these files. For me, the path is
<<path-to-bam>>=
path <- "~/BigData/TERT/bam"
@ 
%% 
As a sanity check, confirm that there are 22 files in this directory,
11 BAM and 11 index files.
<<sanity-check>>=
stopifnot(length(dir(path, "bam$")) == 11)
stopifnot(length(dir(path, "bai$")) == 11)
@ 
%% 
A common challenge in real-world analysis is that the sequence names
used in one part of a work flow (e.g., alignment) differ from sequence
names in another part of the work flow, e.g., annotation. Here the BAM
files are aligned using NCBI notation (``7'') but the annotations
follow UCSC notation (``chr7''). We need to make these consistent, and
it's easier to change the behavior of our annotation packages than to
change the bam files.
<<consistent-names>>=
seqnameStyle(BSgenome.Hsapiens.UCSC.hg19) <- 
    seqnameStyle(TxDb.Hsapiens.UCSC.hg19.knownGene) <- "NCBI"
@ 
%% 
It is important that we think carefully before re-naming sequence names
-- the underlying genome coordinates used for alignment need to match
exactly the genome coordinates used for annotation. As a final
preparation, let's make some convenient abbreviations for our genome
and txdb, and figure out what the Entrez ID is for the gene symbol
TERT.
<<anno-symbols>>=
bsgenome <- BSgenome.Hsapiens.UCSC.hg19
txdb <- TxDb.Hsapiens.UCSC.hg19.knownGene
geneid <- select(org.Hs.eg.db, "TERT", "ENTREZID", "SYMBOL")
@ 

\section{Tallying variants}

\WARNING{This section requires Linux to tally variants with the
  \Biocpkg{gmapR} package}. If you are not using Linux, then read
through the steps and load the \Robject{called} object at the start of
the next section. The necessary precondition to evaluate the code
blocks in this section are tested by the following.
<<VariantTools-setup>>=
VARIANTTOOLS_OK <- local({
    sys <- !Sys.info()["sysname"] %in% c("Darwin", "Windows")
    sys && require(VariantTools) && require(gmapR)
})
stopifnot(VARIANTTOOLS_OK)
@ 

The main goal of this section is to tally variants in our region of
interest. We'll use an algorithm implemented in the
\Rfunction{callVariants} function of the \Biocpkg{VariantTools}
package. This in turn relies on the \Biocpkg{gmapR} package, which
provides an \R{} interface to the GMAP aligner, \Biocpkg{gmapR} needs
a reference genome to do its work. A neat feature is that the
reference genome can be created on the fly from arbitrary nucleotide
sequences. 

TERT is located on chromosome 5 (how would we discover that?) so we
make an indexed mini-reference genome of chr5. We get the coordinates
and actual sequence for this chromosome from the \Rpackage{BSgenome}
package.
<<mini-genome>>=
roi <- GRanges("5", IRanges(1, seqlengths(bsgenome)[["5"]]))
chr5seq <- getSeq(bsgenome, roi)
names(chr5seq) <- "5" 
@ 
%% 
and then make the reference genome in \Biocpkg{gmapR} (\Biocpkg{gmapR}
maintains a cache of sequences, so this is only `expensive' the first
time; it is important to use a descriptive name, because this is the
key used to retrieve a previously built genome from the cache).
<<make-mini>>=
library(gmapR)
genome.5 <- GmapGenome(chr5seq, name="hg19_5", create=TRUE)
@ 

We want to call variants in the promoter region of TERT, so query the
\Rcode{txdb} for transcripts grouped by gene, and then select the TERT
gene from the result. 
<<TERT-promoters>>=
rng <- transcriptsBy(txdb, "gene")[[geneid$ENTREZID]]
@ 
%% 
There are three unique start sites.
<<TERT-starts>>=
unique(start(rng))
@
%% 
For simplicity we treat the gene as a single range (using
\Rfunction{range}), use an \emph{ad hoc} definition of promoter as 330
nt upstream of the transcription start site, and define the
appropriate ranges using \Rfunction{promoter}. We restrict the
seqlevels to just chromosome five (seqlevels are acting in some ways
like factor levels, they persist even if there are no elements with
the corresponding level).
<<TERT-promoter>>=
unique(start(rng))
pregion <- promoters(range(rng), upstream=330, downstream=0)
seqlevels(pregion) <- "5"
@ 
 
Our objective is to use the \Biocpkg{VariantTools} package to call
variants. Variant calling is influenced by parameters specified in
creation of a \Rclass{VariantTallyParam} object; details of the
arguments to this function, and how they influence variant calling,
are present on the \Rfunction{VariantTallyParam} help page and in the
\Biocpkg{VariantTools} vignette.
<<setup-variant-calling>>=
library(VariantTools)
vtparam <- VariantTallyParam(genome.5, readlen=101L, 
    which=pregion, indels=TRUE)
@ 

The next step is to call variants. The basic approach is to invoked
the \Rfunction{callVariants} function on each bam file, using our
\Robject{vtparam} object to influence how variants are called.  
\begin{Exercise}
  (Linux only) Consult section 2.2 of the \Rpackage{VariantTools}
  vignette for a brief description of how variants are called.
\end{Exercise}
The following two lines calls variants in each of our files.
<<call-variants>>=
fls <- dir(path, "bam$", full=TRUE)
called <- lapply(fls, callVariants, tally.param=vtparam)
@                              
%% 
The results can be cleaned up a little. We currently have one
\Robject{GRanges} object for each BAM file, but it's convenient to
create a single \Robject{GRanges} object, adding a column (`id') to
remember which range came from which file.
<<call-variants-tidy>>=
len <- elementLengths(called)
called <- do.call(c, called)
id <- sub(".TERT.bam", "", basename(fls))
called$id <- factor(rep(id, len), levels=unique(id))
@ 
%% 
We'll explore the \Rcode{called} object in the next section.  

\section{Manipulation}

Here we pick up from the previous section, loading a saved version of
the data those of us on Linux were able to create.
<<load-called>>=
data(called, package="Morgan2013")
@ 
%% 
\begin{Exercise}
  What class of object is \Rcode{called}? How many rows does it have?
  How many metadata columns?
\end{Exercise}

\begin{Solution}
  The object is a \Rclass{GRanges} object with length
  \Sexpr{length(called)} and \Sexpr{ncol(mcols(called))} metadata
  columns.
\end{Solution}
  
Each row represents a genomic location for which some evidence of a
variant was discovered. The \Robject{ref} and \Robject{alt} columns
contain the reference and alternate sequence observed at that
location. From the \Biocpkg{VariantTools} package, some of the
important columns are:
\begin{verbatim}
 ncycles: The number of unique cycles at which the alternate allele was
          observed, 'NA' for the reference allele row.
   count: The number of reads with the alternate allele, 'NA' for the
          reference allele row.
high.quality: The number of reads for the alternate allele that were
          above 'high_quality_cutoff', 'NA' for the reference allele
          row.
mean.quality: The mean mapping quality for the alternate allele, 'NA'
          for the reference allele row.
count.pos: The number of positive strand reads for the alternate
          allele, 'NA' for the reference allele row.
cycleCount: An additional column is present for each bin formed by the
          'cycle_breaks' parameter, with the read count for that bin.
\end{verbatim}
Additional columns are also appended with `.ref', `.total', `.pos',
`.neg', etc., to indicate reference, total, positive strand and
negative strand. The idea is that the metadata columns are providing
further guidance on the nature of evidence supporting each called
variant. It is useful to get a sense of the evidence supporting the
called variants by exploring \Robject{called} using standard \R{}
commands, e.g., plotting \Robject{count} and \Robject{count.ref}
columns against one another. The called variants depend critically on
parameters used in \Robject{VariantTallyParam}, so we would want to
spend some time giving calling and quality assessment parameters
careful consideration.

A quick assessment of called variants, sufficient for reproducing
results in \cite{huang2013highly}, can be obtained by plotting the
number of reads supporting each call, across samples. We focus on the
highest-quality read cycles 10 to 91. The result is shown in
Figure~\ref{fig:variant-levelplot}.
<<explore-variants>>=
library(lattice)
altCounts <-
    xtabs(cycleCount.10.91 ~ start(called) + id, mcols(called))
plt <- levelplot(altCounts, xlab="Position", ylab=NULL,
          scales=list(x=list(rot=45)), aspect="fill",
          col.regions=rev(gray.colors(100, 0, 1)))
@ 
<<variant-levelplot, echo=FALSE>>=
pdf("variant-levelplot.pdf", width=10, height=3)
print(plt)
xx <- dev.off()
@ 
\begin{figure}
  \includegraphics[width=\textwidth, height=!]{variant-levelplot.pdf}
  \caption{Called variants across samples in regulatory regions of TERT}
  \label{fig:variant-levelplot}
\end{figure}

\section{Regulatory signatures}

Supposing that we have identified, as Huang \emph{et al}.\ did, a
mutation occurring at position 1295228 across samples or cell
lines. How can we relate this variant to regulatory signature?

We start by extracting the sequence surrounding the SNP in the
reference. We do this by creating a \Robject{GRanges} instance at the
SNP, then selecting flanking sequence of say 10 nt.
<<snp-def>>=
snp <- GRanges("5", IRanges(1295228, width=1))
snp <- flank(snp, 10, both=TRUE)
@ 
%%
We then retrieve the sequence from a data source, e.g., the
\Robject{BSgenome}, \Robject{gmapR}, or \Biocpkg{Rsamtools}'
\Rclass{FaFile} on which alignments were based.
<<ref-seq>>=
refSeq <- getSeq(bsgenome, snp)
@ 
%% 
Alternate sequences are a little more difficult; the helper function
\Rfunction{variantSequences} has been defined to do the work. It takes
the called variants, our SNP regions of interest, and the reference
sequence as arguments. It subsets our called variants to include only
those that overlap our region of interest using
\Rfunction{subsetByOverlaps}. It then injects the variants into the
reference sequence using \Rfunction{replaceLetterAt}.
<<variantSequences>>=
library(Morgan2013)
variantSequences
altSeq <- variantSequences(called, snp, refSeq)
@ 
%% 
We can perform various operations on the alt sequences; here we
suppose a common signal and create a consensus string.
<<alt-seq>>=
altConsensus <- DNAStringSet(consensusString(altSeq))
@ 
%% 
We can see the C228T transition in the middle of a DNAStringSet
containing first the (complements) of the reference and consensus
alternate sequence.
<<complement>>=
complement(c(refSeq, altConsensus))
@ 

The \Biocpkg{MotifDb} package contains a data base of protein binding
motifs. Here we load the data base and query it for all motifs present
in humans and derived from the well-respected JASPAR
core\footnote{\url{http://jaspar.cgb.ki.se/}} data set.
<<pwms>>=
library(MotifDb)
idx <- with(mcols(MotifDb), 
            organism=="Hsapiens" & dataSource == "JASPAR_CORE")
jasparHumanPWMs <- MotifDb[idx]
@ 
%% 
We now run all motifs over the regulatory region, searching for
possible similarity. We do this for the the reference sequence and for
the alternative consensus.
<<pwm-match>>=
## matchPWMs: helper in Morgan2013
minScore = "90%"             # high min. matching score: 1 base change
(refHits <- matchPWMs(jasparHumanPWMs, reverseComplement(refSeq)[[1]],
                      minScore))
(altHits <- matchPWMs(jasparHumanPWMs, reverseComplement(altConsensus)[[1]],
                      minScore))
@ 
%% 
Comparison of results shows that the consensus sequence contains a
novel high-scoring binding site for ETS1, as reported in Huang et al.

\section{Conclusions}

This work flow has provided brief tour through key steps in calling
regulatory variants, using previous results by Huang et al., to
motivate identification of a novel binding motif associated with
introduction of a called variant. Major components of this work flow
include the \Biocpkg{VariantTools}, \Biocpkg{Biostrings}, and
\Biocpkg{MotifDb} packages.
