--- title: "B. AlphaFold Integration" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{B. AlphaFold Integration} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ``` Original version: 31 October, 2023 # Introduction This vignette illustrates how to display [AlphaMissense][] predictions on [AlphaFold][] predicted protein structure. [AlphaMissense]: https://www.science.org/doi/10.1126/science.adg7492 [AlphaFold]: https://alphafold.ebi.ac.uk/ Visualization makes use of CRAN packages [bio3d][] and [r3dmol][]. Install these (if necessary) with [bio3d]: https://CRAN.R-project.org/package=bio3d [r3dmol]: https://CRAN.R-project.org/package=r3dmol ```{r dependencies, eval = FALSE} pkgs <- c("bio3d", "r3dmol") pkgs_to_install <- pkgs[!pkgs %in% rownames(installed.packages())] if (length(pkgs_to_install)) BiocManager::install(pkgs_to_install) ``` Start by loading the [AlphaMissenseR][] library. [AlphaMissenseR]: https://mtmorgan.github.io/AlphaMissenseR ```{r setup, message = FALSE} library(AlphaMissenseR) ``` Visit the summary of available AlphaMissense datasets ```{r am_available} am_available() ``` This vignette uses the `aa_substitutions` and `hg38` data resources; make sure that these have been cached locally. ```{r am_data} am_data("aa_substitutions") am_data("hg38") ``` # AlphaFold protein structure AlphaMissense predictions on pathogenicity of amino acid changes can be combined with AlphaFold (or other) predictions of protein structure. ## Fast path Figure 3F of the [AlphaMissense][] publication visualizes mean pathogenicity for UniProt id P35557. Filter amino acid data for that identifier ```{r P35557} P35557_aa <- am_data("aa_substitutions") |> dplyr::filter(uniprot_id == "P35557") ``` and visualization median pathogenicity with ```{r median-pathogenicity} af_prediction_view(P35557_aa) ``` The image is interactive, including rotation and zoom. The following sections explore this visualization in more detail. ## UniProt identifiers Both AlphaMissense and AlphaFold use UniProt identifiers. Find all AlphaMissense amino acid substitutions with UniProt identifiers starting with `P3555`; the choice of this identifier is so that results can be compared with Figure 3F of the [AlphaMissense][] publication. ```{r uniprot_ids} uniprot_ids <- am_data("aa_substitutions") |> dplyr::filter(uniprot_id %like% "P3555%") |> dplyr::distinct(uniprot_id) |> pull(uniprot_id) uniprot_ids ``` The [AlphaMissenseR][] package includes several functions that facilitate interaction with [AlphaFold][]; these functions start with `af_*()`. Use `af_predictions()` to discover AlphaFold predictions (via the AlphaFold API) associated with UniProt identifiers. ```{r af_predictions} prediction <- af_predictions(uniprot_ids) glimpse(prediction) ``` Note the message indicating that some UniProt identifiers (accessions) are not found in the AlphaFold database. The query returns a tibble containing columns with information on organism and UniProt characteristics (including protein sequence) , as well as URLs for files representing three-dimensional protein structure. We will use `pdbUrl`. ## Protein structure Focus on a particular UniProt identifier and the PDB url. ```{r pdb_url} pdb_url <- prediction |> dplyr::filter(uniprotAccession == "P35557") |> dplyr::pull(pdbUrl) ``` Cache the PDB file using BiocFileCache, and read the PDB file using [bio3d][]. ```{r pdb} pdb_file <- BiocFileCache::bfcrpath(rnames = basename(pdb_url), fpath = pdb_url) pdb <- bio3d::read.pdb(pdb_file) pdb ``` Visualize the protein using [r3dmol][], using the 'cartoon' style. ```{r pdb_r3dmol} r3dmol::r3dmol() |> ## use the PDB representation r3dmol::m_add_model(r3dmol::m_bio3d(pdb)) |> ## visualize as a 'cartoon' with alpha helices and beta sheets r3dmol::m_set_style(style = r3dmol::m_style_cartoon(arrow = TRUE)) |> ## fit molecule into display area r3dmol::m_zoom_to() ``` ## Average pathogenicity Our goal is to visualize some measure of 'average' pathogenicity on the three-dimensional protein structure provided by AlphaFold. Start with a specific genome sequence (e.g., `hg38`). Filter to the amino acids in our UniProt region of interest. ```{r am_data-hg38} P35557 <- am_data("hg38") |> dplyr::filter(uniprot_id == "P35557") ``` At each chromosome position, the AlphaMissense predictions contain several alternative alleles and hence protein variants. The (arithmetic) average pathogenicity (this is an extremely naive computation) at each amino acid position is ```{r am_aa_pathogenicity} pathogenicity <- am_aa_pathogenicity(P35557) pathogenicity ``` ## Coloring amino acids by position Individual amino acids can be colored using the `colorfunc=` argument to `r3dmol::m_style_cartoon()`. This is a Javascript function that takes each atom position and returns the corresponding color. The approach taken in [AlphaMissenseR][] is to use a template, ultimately replacing `...` with a vector of residue colors. ```{r js_template} cat( AlphaMissenseR:::js_template("colorfunc", colors = "..."), "\n" ) ``` The function `af_colorfunc_by_position()` provides a mechanism for translating a vector of scores between zero and one into a vector of colors. This is illustrated for a 12-amino acid sequence where the first and last residues are uncolored. ```{r af_colorfunc_by_position} df <- tibble( pos = 1 + 1:10, # no color information for position 1 value = 10:1 / 10 ) colorfunc <- af_colorfunc_by_position( df, "pos", "value", pos_max = 12 # no color information for position 12 ) cat(colorfunc, "\n") ``` The following color function is similar to that used in `af_prediction_view()`, but uses the mean rather than median pathogenicity and scales the palette between the minimum and maximum values of the mean pathogenicity vector, rather than between 0 and 1. ```{r colorfunc} colorfunc <- pathogenicity |> af_colorfunc_by_position( "aa_pos", "aa_pathogenicity_mean", length(pdb$seqres) ) ``` Add this as the `colorfunc=` argument to `m_style_cartoon()` for visualization. ```{r pdb_r3dmol_color} r3dmol::r3dmol() |> ## use the PDB representation r3dmol::m_add_model(r3dmol::m_bio3d(pdb)) |> ## visualize as a 'cartoon' with alpha helices and beta sheets r3dmol::m_set_style( style = r3dmol::m_style_cartoon( arrow = TRUE, ## color residue according to colorfunc colorfunc = colorfunc ) ) |> ## fit molecule into display area r3dmol::m_zoom_to() ``` # Visualizing genomic tracks The variant effect prediction data can also be visualized in a genome browser view. This allows the user to explore the predicted pathogenicity of single nucleotide missense mutations in a gene of interest. This multi-scale visualization is based on [Gosling][], a grammar-based toolkit for scalable and interactive genomics data visualization. [Gosling]: https://gosling-lang.org/ For demonstration, we create a `GPos` object for a protein of interest. ```{r mk_gpos, message=FALSE} gpos <- am_data("hg38") |> filter(uniprot_id == "Q1W6H9") |> to_GPos() ``` The function `plot_granges` invokes functionality from the [shiny.gosling][] package to produce an interactive genome track plot in which the pathogenicity score for each point mutation in a linear genomic track. The resulting plot is a [Shiny][] app that can be displayed when running the following command in an interactive R session. [shiny.gosling]: https://bioconductor.org/packages/shiny.gosling [Shiny]: https://shiny.posit.co/ ```{r gosling_bar} gosling_plot( gpos, plot_type = "bar", title = "Q1W6H9 track", subtitle = "bar plot example" ) ``` ![Bar plot for Q1W6H9](images/gosling_bar.png) Alternatively, a multiscale-lollipop plot can be generated with the same function by changing the `plot_type` argument to highlight the predicted class outcomes for each mutation (ambigious, benign, pathogenic). ```{r gosling_lollipop} gosling_plot( gpos, plot_type = "lollipop", title = "Q1W6H9 track", subtitle = "lollipop plot example" ) ``` ![Lollipop plot for Q1W6H9](images/gosling_lollipop.png) # Finally Remember to disconnect and shutdown all managed DuckDB connections. ```{r db_disconnect_all} db_disconnect_all() ``` Database connections that are not closed correctly trigger warning messages. # Session information {.unnumbered} ```{r sessionInfo} sessionInfo() ```