diff --git a/app.R b/app.R
index 487c360..93d9167 100644
--- a/app.R
+++ b/app.R
@@ -34,8 +34,8 @@ options(DT.options = list(scrollX = TRUE))
# Gitea access token
access_token = read_lines("~/secret-token")
-gene_url = "https://git.tunstall.in/api/v1/repos/tanu/fellowship_dcdf/raw/tb_data_fc/dashboard/list_unique_missense_genes.csv"
-missense_gene_url = "https://git.tunstall.in/api/v1/repos/tanu/fellowship_dcdf/raw/tb_data_fc/dashboard/missense_genes_params.csv"
+gene_url = "https://git.tunstall.in/api/v1/repos/tanu/fellowship_dcdf/raw/tb_data_fc/data_dashboard/list_unique_missense_genes.csv"
+missense_gene_url = "https://git.tunstall.in/api/v1/repos/tanu/fellowship_dcdf/raw/tb_data_fc/data_dashboard/missense_genes_params.csv"
alphafold_url = "https://alphafold.ebi.ac.uk/files/"
genes=read_csv(paste0(gene_url,"?token=",access_token))
@@ -229,7 +229,10 @@ server <- function(input, output) {
#"PROVEAN: ", as.character(unique_missense_genes[input$table_rows_selected,"provean_score"]), "
",
"PROVEAN Outcome: ", as.character(unique_missense_genes[input$table_rows_selected,"provean_outcome"]), "
",
"RSA: ", as.character(unique_missense_genes[input$table_rows_selected,"rsa"]), "
",
- "Residue Depth: ", as.character(unique_missense_genes[input$table_rows_selected,"rd_values"]), "
"
+ "Residue Depth: ", as.character(unique_missense_genes[input$table_rows_selected,"rd_values"]), "
",
+ "Total Samples: ", as.character(unique_missense_genes[input$table_rows_selected,"total_sample_count"]), "
",
+ "Distinct Lineages: ", as.character(unique_missense_genes[input$table_rows_selected,"distinct_lineage_count"]), "
"
+
)
)
@@ -286,7 +289,7 @@ server <- function(input, output) {
opacity = 0.2
)
) %>%
- addSelection(type="spacefill",
+ addSelection(type="ball+stick", #spacefill
param = list(name = "all_mutations",
color="orange",
sele = mutations
@@ -304,7 +307,7 @@ server <- function(input, output) {
opacity = 0.2
)
) %>%
- addSelection(type="spacefill",
+ addSelection(type="ball+stick", #spacefill
param = list(name = "all_mutations",
color="orange",
sele = mutations
@@ -318,3 +321,4 @@ server <- function(input, output) {
# Run the application
shinyApp(ui = ui, server = server)
+
diff --git a/server.R b/server.R
new file mode 100644
index 0000000..1a4a43a
--- /dev/null
+++ b/server.R
@@ -0,0 +1,238 @@
+library(shiny)
+library(shinyjs)
+library(shinydashboard)
+#library("wesanderson") # ayyyy lmao hipster af
+library(dplyr)
+library(DT)
+library(ggplot2)
+library(grid) # for the info box
+library(plotly)
+library(shinycssloaders)
+library(NGLVieweR)
+library(httr)
+library(readr)
+library(RCurl)
+
+shinyServer(function(input, output) {
+
+ output$distPlot <- renderPlot({
+ # generate bins based on input$bins from ui.R
+ x <- faithful[, 2]
+ bins <- seq(min(x), max(x), length.out = input$bins + 1)
+
+ # draw the histogram with the specified number of bins
+ hist(x, breaks = bins, col = 'darkgray', border = 'white',
+ xlab = 'Waiting time to next eruption (in mins)',
+ main = 'Histogram of waiting times')
+ })
+ ### NGLViewer ####
+ # Structure Viewer WebGL/NGLViewR window
+ output$structure <- renderNGLVieweR({
+ selected_gene=input$gene
+ ngl_gene=as.character(genes[genes$Gene==selected_gene,"PDB"])
+ NGLVieweR(ngl_gene) %>%
+ addRepresentation("cartoon",
+ param = list(name = "cartoon",
+ color="tan",
+ #colorScheme = "bfactor",
+ opacity = 1
+ )
+ ) %>%
+ stageParameters(backgroundColor = "white") %>%
+ setQuality("high") %>%
+ setFocus(0) %>%
+ setSpin(FALSE)
+ })
+ output$af_structure <- renderNGLVieweR({
+ selected_af_gene=input$gene
+ ngl_af_gene=as.character(genes[genes$Gene==selected_af_gene,"AF_PDB"])
+
+ #af_pdb=cat(content(GET(paste0(alphafold_url,"AF-",ngl_af_gene,"-F1-model_v4.pdb")), as="text"), "\n")
+ af_pdb=content(GET(paste0(alphafold_url,"AF-",ngl_af_gene,"-F1-model_v4.pdb")), as="text")
+ #print(af_pdb)
+ #ngl_pdb_file=paste0(load_dir, "Data/", ngl_drug, '/output/depth/', ngl_gene, '_complex.pdb')
+ NGLVieweR(af_pdb, format="pdb") %>%
+ addRepresentation("cartoon",
+ param = list(name = "cartoon",
+ #color="tan"
+ colorScheme = "bfactor",
+ opacity = 1
+ )
+ ) %>%
+ stageParameters(backgroundColor = "white") %>%
+ setQuality("high") %>%
+ setFocus(0) %>%
+ setSpin(FALSE)
+ })
+
+ # output$table <- DT::renderDataTable({
+ # selected_gene=input$gene
+ # gene=as.character(genes[genes$Gene==selected_gene,"Gene"])
+ # #unique_missense_genes[unique_missense_genes$gene_name==gene,]
+ # unique_missense_genes
+ # },
+ # selection = "single",
+ # search = list(search="alr"))
+ output$table <- DT::renderDataTable(
+ unique_missense_genes,
+ selection = "single",
+ options=list(
+ search = list(search=as.character(genes[genes$Gene==input$gene,"Gene"]))
+ )
+ )
+
+ observeEvent(input$table_rows_selected,{
+ #req(length(input$table_row_selected) > 0)
+ mutation = as.character(unique_missense_genes[input$table_rows_selected,"hgvd_p"])
+ chain = as.character(unique_missense_genes[input$table_rows_selected,"chain"])
+ # what the absolute FUCK is this mess? I JUST WANT THE MATCH ASDLASJASDASHFKLJASDFK
+ # coming down from the trees was a mistake, and abandoning Perl doubly so.
+ clicked_position = regmatches(mutation, regexpr("[0-9]+", mutation, perl=TRUE))
+
+ # Now update the 3D structure to highlight the clicked thing and then zoom in.
+
+ NGLVieweR_proxy("structure") %>%
+ #addSelection('ball+stick'
+ addSelection('spacefill'
+ , param = list(
+ name = "Pos"
+ , sele = trimws(paste0(clicked_position,':', chain))
+ , color = "red"
+ #, colorValue="00ff00"
+ #, colorScheme="element"
+ )
+ )
+ NGLVieweR_proxy("af_structure") %>%
+ #addSelection('ball+stick'
+ addSelection('spacefill'
+ , param = list(
+ name = "Pos"
+ , sele = clicked_position
+ , color = "red"
+ #, colorValue="00ff00"
+ #, colorScheme="element"
+ )
+ )
+
+ NGLVieweR_proxy("af_structure") %>% updateZoomMove(
+ center = clicked_position,
+ zoom = clicked_position,
+ duration = 1000, # animation time in ms
+ z_offSet = -1
+ )
+ NGLVieweR_proxy("structure") %>% updateZoomMove(
+ center = trimws(paste0(clicked_position,':', chain)),
+ zoom = trimws(paste0(clicked_position,':', chain)),
+ duration = 1000, # animation time in ms
+ z_offSet = -1
+ )
+ output$information <- renderUI({
+ selected_gene=input$gene
+ HTML(paste0("Mutation: ", as.character(unique_missense_genes[input$table_rows_selected,"mutationinformation"]),"
",
+ "PDB ID: ", as.character(genes[genes$Gene==selected_gene,"PDB"]),"
",
+ "AlphaFold ID: ", as.character(genes[genes$Gene==selected_gene,"AF_PDB"]), "
",
+ "Ligand Distance: ", as.character(unique_missense_genes[input$table_rows_selected,"ligand_distance"]), "
",
+ "mCSM Lig: ", as.character(unique_missense_genes[input$table_rows_selected,"mcsm_lig"]), "
",
+ "mmCSM Lig: ", as.character(unique_missense_genes[input$table_rows_selected,"mmcsm_lig"]), "
",
+ "mCSM DUET: ", as.character(unique_missense_genes[input$table_rows_selected,"ddg_duet"]), "
",
+ "FoldX: ", as.character(unique_missense_genes[input$table_rows_selected,"ddg_foldx"]), "
",
+ "DeepDDG: ", as.character(unique_missense_genes[input$table_rows_selected,"ddg_deepddg"]), "
",
+ "Dynamut2: ", as.character(unique_missense_genes[input$table_rows_selected,"ddg_dynamut2"]), "
",
+ "mCSM PPI2: ", as.character(unique_missense_genes[input$table_rows_selected,"mcsm_ppi2_affinity"]), "
",
+ "Interface Distance: ", as.character(unique_missense_genes[input$table_rows_selected,"interface_dist"]), "
",
+ "mCSM NA: ", as.character(unique_missense_genes[input$table_rows_selected,"mcsm_na_affinity"]), "
",
+ "Consurf: ", as.character(unique_missense_genes[input$table_rows_selected,"consurf_score"]), "
",
+ #"SNAP2: ", as.character(unique_missense_genes[input$table_rows_selected,"snap2_score"]), "
",
+ "SNAP2 Outcome: ", as.character(unique_missense_genes[input$table_rows_selected,"snap2_outcome"]), "
",
+ #"PROVEAN: ", as.character(unique_missense_genes[input$table_rows_selected,"provean_score"]), "
",
+ "PROVEAN Outcome: ", as.character(unique_missense_genes[input$table_rows_selected,"provean_outcome"]), "
",
+ "RSA: ", as.character(unique_missense_genes[input$table_rows_selected,"rsa"]), "
",
+ "Residue Depth: ", as.character(unique_missense_genes[input$table_rows_selected,"rd_values"]), "
",
+ "Total Samples: ", as.character(unique_missense_genes[input$table_rows_selected,"total_sample_count"]), "
",
+ "Distinct Lineages: ", as.character(unique_missense_genes[input$table_rows_selected,"distinct_lineage_count"]), "
"
+
+ )
+ )
+
+ })
+
+ # output$debug <- renderPrint({
+ # print(c(mutation, clicked_position))
+ # })
+ })
+ observeEvent(
+ {
+ input$clear_ngl
+ }, {
+ NGLVieweR_proxy("structure") %>%
+ removeSelection("Pos") %>%
+ removeSelection("all_mutations_surface") %>%
+ updateVisibility("cartoon", TRUE) %>%
+ removeSelection("all_mutations")
+ NGLVieweR_proxy("af_structure") %>%
+ removeSelection("Pos") %>%
+ removeSelection("all_mutations_surface") %>%
+ updateVisibility("cartoon", TRUE) %>%
+ removeSelection("all_mutations")
+ })
+ # add a surface representation and highlight all mutations on it
+ observeEvent(
+ {
+ input$all_mutations
+ }, {
+ gene = input$gene
+ mutations = paste0(":",
+ as.matrix(unique_missense_genes[unique_missense_genes$gene_name == gene,c("chain")])[1],
+ " and (",
+ paste0(
+ apply(
+ unique_missense_genes[unique_missense_genes$gene_name == gene,c("position","chain")],
+ 1,
+ function(x){
+ paste0(trimws(x[1])
+ )}
+ ),
+ collapse=", "
+ ), ")"
+ )
+ #print(mutations)
+
+
+ NGLVieweR_proxy("structure") %>%
+ updateVisibility("cartoon", FALSE) %>%
+ addSelection(type="cartoon",
+ param = list(name = "all_mutations_surface",
+ sele = "all",
+ color="tan",
+ opacity = 0.2
+ )
+ ) %>%
+ addSelection(type="ball+stick", #spacefill
+ param = list(name = "all_mutations",
+ color="orange",
+ sele = mutations
+ #colorScheme = "bfactor",
+ #opacity = 1
+ )
+ )
+ NGLVieweR_proxy("af_structure") %>%
+ updateVisibility("cartoon", FALSE) %>%
+ addSelection(type="cartoon",
+ param = list(name = "all_mutations_surface",
+ sele = "all",
+ #color="tan",
+ colorScheme = "bfactor",
+ opacity = 0.2
+ )
+ ) %>%
+ addSelection(type="ball+stick", #spacefill
+ param = list(name = "all_mutations",
+ color="orange",
+ sele = mutations
+ #colorScheme = "bfactor",
+ #opacity = 1
+ )
+ )
+ })
+}
+)
diff --git a/ui.R b/ui.R
new file mode 100644
index 0000000..5c50730
--- /dev/null
+++ b/ui.R
@@ -0,0 +1,66 @@
+library(shiny)
+library(shinyjs)
+library(shinydashboard)
+#library("wesanderson") # ayyyy lmao hipster af
+library(dplyr)
+library(DT)
+library(ggplot2)
+library(grid) # for the info box
+library(plotly)
+library(shinycssloaders)
+library(NGLVieweR)
+library(httr)
+library(readr)
+library(RCurl)
+
+dashboardPage(skin="purple",
+ dashboardHeader(title="Tuberculosis Host"),
+ dashboardSidebar(
+ radioButtons("gene",
+ label="Gene",
+ choices = genes$Gene,
+ selected="alr" # "alr" is a value
+ ),
+ actionButton("clear_ngl",
+ "Reset Structures"),
+ actionButton("all_mutations",
+ "All Mutations")
+ ),
+ dashboardBody(
+ useShinyjs(),
+ fluidRow(
+ box(
+ title="Crystallised Structure",
+ width=5,
+ column(
+ NGLVieweROutput("structure"),
+ width=12
+ )
+ ),
+ box(
+ title="AlphaFold Structure",
+ width=5,
+ column(
+ NGLVieweROutput("af_structure"),
+ width=12
+ )
+ ),
+ box(
+ title="Mutation Information",
+ width=2,
+ column(
+ htmlOutput("information"),
+ width=12
+ )
+ )
+ ),
+ fluidRow(
+ column(
+ DT::dataTableOutput('table'),
+ width=12
+ )
+ ),
+ verbatimTextOutput("debug")
+ )
+)
+