# # This is a Shiny web application. You can run the application by clicking # the 'Run App' button above. # # Find out more about building applications with Shiny here: # # http://shiny.rstudio.com/ # 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) # make shiny non-stupid options(shiny.launch.browser = FALSE) # i am a big girl and can tie my own laces options(shiny.port = 8000) # don't change the port every time options(shiny.host = '0.0.0.0') # This means "listen to all addresses on all interfaces" options(DT.options = list(scrollX = TRUE)) # An "application token" is required here. I generated this one like this: # curl -H "Content-Type: application/json" -d '{"name":"r-data"}' -u : https://git.tunstall.in/api/v1/users/sethp/tokens # 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" alphafold_url = "https://alphafold.ebi.ac.uk/files/" genes=read_csv(paste0(gene_url,"?token=",access_token)) unique_missense_genes = read_delim(paste0(missense_gene_url,"?token=",access_token)) #genes = c("Gene 1", "Gene 2", "Gene 3", "Gene 4", "Gene 5") # Define UI for application that draws a histogram ui=dashboardPage(skin="purple", dashboardHeader(title="Tuberculosis Host"), dashboardSidebar( radioButtons("gene", label="Gene", choices = genes$Gene, selected="alr" # "alr" is a value ), actionButton("clear_ngl", "Clear Structures") ), dashboardBody( useShinyjs(), fluidRow( box( title="Crystallised Structure", column( NGLVieweROutput("structure"), width=12 ) ), box( title="AlphaFold Structure", column( NGLVieweROutput("af_structure"), width=12 ) ) ), fluidRow( column( DT::dataTableOutput('table'), width=12 ) ), verbatimTextOutput("debug") ) ) # Define server logic required to draw a histogram server <- 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"]) # 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('ball+stick' , param = list( name = "Pos" , sele = clicked_position , color = "green" #, colorValue="00ff00" #, colorScheme="element" ) ) NGLVieweR_proxy("af_structure") %>% #addSelection('ball+stick' addSelection('ball+stick' , param = list( name = "Pos" , sele = clicked_position , color = "green" #, 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 = clicked_position, zoom = clicked_position, duration = 1000, # animation time in ms z_offSet = -1 ) # output$debug <- renderPrint({ # print(c(mutation, clicked_position)) # }) }) observeEvent( { input$clear_ngl }, { NGLVieweR_proxy("structure") %>% removeSelection("Pos") NGLVieweR_proxy("af_structure") %>% removeSelection("Pos") }) } # Run the application shinyApp(ui = ui, server = server)