From 0fee29b91771daa3e436c1ad8e899eae159e6ca9 Mon Sep 17 00:00:00 2001 From: jvsguerra Date: Mon, 27 Mar 2023 16:13:37 -0300 Subject: [PATCH] Add multimodel input to KVFinder-web portal (#32) * add multimodel selection --------- Co-authored-by: Helder Ribeiro --- kvfinder-web-portal/R/app_server.R | 18 ++++---- .../R/mod_server_checkResults.R | 2 + kvfinder-web-portal/R/mod_server_pdbProcess.R | 9 ++-- kvfinder-web-portal/R/utils_pdbProcess_.R | 42 +++++++++++++++---- kvfinder-web-portal/man/deal_sele_nonstand.Rd | 8 +++- kvfinder-web-portal/man/report_nonstand.Rd | 4 +- 6 files changed, 60 insertions(+), 23 deletions(-) diff --git a/kvfinder-web-portal/R/app_server.R b/kvfinder-web-portal/R/app_server.R index d24397d..b113c1c 100644 --- a/kvfinder-web-portal/R/app_server.R +++ b/kvfinder-web-portal/R/app_server.R @@ -67,13 +67,10 @@ app_server <- function(input, output, session) { observeEvent(input$input_pdb, { # run process_upload of mod_server_upload module to create boxes and buttons of run mode process_upload(input = input, output = output, session = session) - get_nonstand_check_upload <<- report_nonstand(pdb_input =input$input_pdb$datapath) + get_nonstand_check_upload <<- report_nonstand(pdb_input =input$input_pdb$datapath, show_modal=TRUE) }) observeEvent(input$show_preview_upload, { - print(input$input_pdb$datapath) - print(pdb_name_click_load) - print(get_nonstand) showModal(modalDialog( #title = tags$a('Structure preview', style = "text-align: right;" ), #NGLVieweROutput("structure_prev", width = "100%", height = "75vh"), @@ -82,11 +79,13 @@ app_server <- function(input, output, session) { renderNGLVieweR({ # get input protein PDB with output cavities pdb <- input$input_pdb$datapath + print(paste("/",as.numeric(input$model_number),sep="")) # create initial scene NGLVieweR(pdb) %>% # start protein with visible cartoon representation - addRepresentation("cartoon") %>% - addRepresentation("ball+stick", param = list(sele = paste(get_nonstand_check_upload, collapse = " or "))) %>% + addRepresentation("cartoon", param=list(sele = paste("/",as.numeric(input$model_number)-1,sep=""))) %>% + addRepresentation("ball+stick", param = list(sele = paste(paste(get_nonstand_check_upload, collapse = " or "),"/",as.numeric(input$model_number)-1,sep=""))) %>% + # start cavity with points stageParameters(backgroundColor = "black") %>% setQuality("high") %>% @@ -111,8 +110,7 @@ app_server <- function(input, output, session) { pdb_name_click_load <<- input$pdb_id # check if the PDB code is valid by using get_nonstand showModal(modalDialog("Loading and checking PDB...", footer = NULL, fade = FALSE)) - get_nonstand_check <<- report_nonstand(pdb_input = input$pdb_id) - print(get_nonstand_check) + get_nonstand_check <<- report_nonstand(pdb_input = input$pdb_id, show_modal=TRUE) removeModal() if (length(which(is.na(get_nonstand_check))) != 0) { shinyWidgets::sendSweetAlert(session = session, title = "Oops!", text = "Please insert a valid PDB ID.", type = "error") @@ -137,8 +135,8 @@ app_server <- function(input, output, session) { # create initial scene NGLVieweR(pdb) %>% # start protein with visible cartoon representation - addRepresentation("cartoon") %>% - addRepresentation("ball+stick", param = list(sele = paste(get_nonstand_check, collapse = " or "))) %>% + addRepresentation("cartoon", param=list(sele = paste("/",as.numeric(input$model_number)-1,sep=""))) %>% + addRepresentation("ball+stick", param = list(sele = paste(paste(get_nonstand_check, collapse = " or "),"/",as.numeric(input$model_number)-1,sep=""))) %>% # start cavity with points stageParameters(backgroundColor = "black") %>% setQuality("high") %>% diff --git a/kvfinder-web-portal/R/mod_server_checkResults.R b/kvfinder-web-portal/R/mod_server_checkResults.R index d51d968..1da29fb 100644 --- a/kvfinder-web-portal/R/mod_server_checkResults.R +++ b/kvfinder-web-portal/R/mod_server_checkResults.R @@ -72,8 +72,10 @@ check_results <- function(input, output, run_id, is_pg2, url_address, session) { retrieve_content <- content(retrieve_get) # get retrivied input PDB retrieve_input_pdb <- retrieve_content$input$pdb + print(content_get_output$output$report) # table with results result_toml <- parseTOML(input = content_get_output$output$report, fromFile = FALSE, escape = TRUE)$RESULTS + #print(result_toml$AREA) #print(names(result_toml)) #print(result_toml$MAX_DEPTH) # check if the at least one cavity was found diff --git a/kvfinder-web-portal/R/mod_server_pdbProcess.R b/kvfinder-web-portal/R/mod_server_pdbProcess.R index 0c14acc..7de6c7f 100644 --- a/kvfinder-web-portal/R/mod_server_pdbProcess.R +++ b/kvfinder-web-portal/R/mod_server_pdbProcess.R @@ -26,10 +26,11 @@ pdb_process <- function(input, output, get_nonstand, mode, session) { } # create a processed PDB for each run mode: default, customized, ligand or box mode if (input$run_mode == "mode_def") { - pdb_processed <- deal_sele_nonstand(pdb_input = pdb_input, nonstand_list = get_nonstand, include_list = include_list, session = session) + + pdb_processed <- deal_sele_nonstand(input=input,pdb_input = pdb_input, nonstand_list = get_nonstand, include_list = include_list, session = session) pdb_processed <- list(pdb_processed = pdb_processed) } else if (input$run_mode == "mode_cust") { - pdb_processed <- deal_sele_nonstand(pdb_input = pdb_input, nonstand_list = get_nonstand, include_list = include_list, session = session) + pdb_processed <- deal_sele_nonstand(input=input,pdb_input = pdb_input, nonstand_list = get_nonstand, include_list = include_list, session = session) pdb_processed <- list(pdb_processed = pdb_processed) } else if (input$run_mode == "box_mode") { # in the case of running the box mode, we have to check if the target residues are correctly in the PDB input @@ -38,7 +39,7 @@ pdb_process <- function(input, output, get_nonstand, mode, session) { shinyWidgets::sendSweetAlert(session = session, title = "Oops!", text = "Please insert a valid list of residues for box mode run.", type = "error") pdb_processed <- "wrong_target_res" } else { - pdb_processed <- deal_sele_nonstand(pdb_input = pdb_input, nonstand_list = get_nonstand, include_list = include_list, session = session) + pdb_processed <- deal_sele_nonstand(input=input,pdb_input = pdb_input, nonstand_list = get_nonstand, include_list = include_list, session = session) pdb_processed <- list(pdb_processed = pdb_processed) } } else { # enter in the ligand mode @@ -47,7 +48,7 @@ pdb_process <- function(input, output, get_nonstand, mode, session) { # update nonstandard residues list to exclude the ligand get_nonstand_noLig <- setdiff(get_nonstand, input$lig_name) # get all non-standand but the ligand # by default remove all non standards residues and the ligand - pdb_processed <- deal_sele_nonstand(pdb_input = pdb_input, nonstand_list = c(get_nonstand, input$lig_name), include_list = include_list, session = session) + pdb_processed <- deal_sele_nonstand(input=input,pdb_input = pdb_input, nonstand_list = c(get_nonstand, input$lig_name), include_list = include_list, session = session) pdb_processed <- list(pdb_processed = pdb_processed, pdb_lig_processed = pdb_ligand_processed) } return(pdb_processed) diff --git a/kvfinder-web-portal/R/utils_pdbProcess_.R b/kvfinder-web-portal/R/utils_pdbProcess_.R index 8e4d17d..bff0efe 100644 --- a/kvfinder-web-portal/R/utils_pdbProcess_.R +++ b/kvfinder-web-portal/R/utils_pdbProcess_.R @@ -4,13 +4,19 @@ #' Get non standard protein/nucleic residues from PDB #' #' @param pdb_input Pdb path +#' @param show_modal #' #' @import bio3d #' #' @examples #' @export -report_nonstand <- function(pdb_input) { +report_nonstand <- function(pdb_input, show_modal) { + if(missing(show_modal)){ #in some calls there's no need to inform the if want to use the show modal presented below for multi models + show_modal = FALSE + } else{ + show_modal = show_modal + } pdb <- tryCatch( { read.pdb(pdb_input, multi = T) @@ -21,8 +27,16 @@ report_nonstand <- function(pdb_input) { ) if (class(pdb)[1] == "pdb") { # check multimodels - if (class(pdb)[1] == "pdb" & dim(pdb$xyz)[1] > 1) { - shinyWidgets::sendSweetAlert(title = "Oops!", text = "A multimodel structure was detected as input: Using only the first structure from the multimodel...", type = "warning") + if (class(pdb)[1] == "pdb" & dim(pdb$xyz)[1] > 1 & show_modal == TRUE) { + #shinyWidgets::sendSweetAlert(title = "Oops!", text = "A multimodel structure was detected as input: Using only the first structure from the multimodel...", type = "warning") + showModal(modalDialog( + tags$h3('The input contains multiple models.'), + tags$h5('Please select a single model below:'), + selectInput('model_number', 'Model number',seq(1,dim(pdb$xyz)[1])), + footer=tagList( + modalButton('Select') + ) + )) } # get protein indx_p <- atom.select(pdb, string = "protein", inverse = TRUE) @@ -45,6 +59,7 @@ report_nonstand <- function(pdb_input) { #' @description #' Process PDB file according to the selected non-standard residues #' +#' @param input #' @param pdb_input Pdb path #' @param nonstand_list List of non-standard residues #' @param include_list List of non-standard residues that must be maintained in the PDB @@ -57,11 +72,14 @@ report_nonstand <- function(pdb_input) { #' @export #' -deal_sele_nonstand <- function(pdb_input, nonstand_list, include_list, session = session) { +deal_sele_nonstand <- function(input,pdb_input, nonstand_list, include_list, session = session) { tryCatch( { # test if the pdb_input is an appropriated PDB ID and if the read,pdb function can download successfully this pdb - pdb <- read.pdb(pdb_input) + pdb <- read.pdb(pdb_input, multi=T) + print(dim(pdb$xyz)[1]) + print(include_list) if (is.null(include_list)) { + # get nonstandard selected indx_s <- atom.select(pdb, resid = nonstand_list, inverse = TRUE) # subset pdb @@ -70,7 +88,11 @@ deal_sele_nonstand <- function(pdb_input, nonstand_list, include_list, session = rand <- sample(x = 1:100000, size = 1) outfile <- file.path(tempdir(), paste(rand, ".pdb", sep = "")) # write tmp - write.pdb(pdb = clean_pdb, file = outfile) + if(dim(pdb$xyz)[1] > 1){ #case of multimodel, use the model selected by the user + write.pdb(pdb = clean_pdb, file = outfile, xyz=clean_pdb$xyz[as.numeric(input$model_number),]) + } else{ + write.pdb(pdb = clean_pdb, file = outfile) + } return(outfile) } else { indx_s <- atom.select(pdb, resid = nonstand_list, inverse = TRUE) @@ -81,7 +103,13 @@ deal_sele_nonstand <- function(pdb_input, nonstand_list, include_list, session = rand <- sample(x = 1:100000, size = 1) outfile <- file.path(tempdir(), paste(rand, ".pdb", sep = "")) # write tmp - write.pdb(pdb = clean_pdb, file = outfile) + if(dim(pdb$xyz)[1] > 1){#case of multimodel, use the model selected by the user + print(input$model_number) + print('multimodel') + write.pdb(pdb = clean_pdb, file = outfile, xyz=clean_pdb$xyz[as.numeric(input$model_number),]) + } else{ + write.pdb(pdb = clean_pdb, file = outfile) + } return(outfile) } }, diff --git a/kvfinder-web-portal/man/deal_sele_nonstand.Rd b/kvfinder-web-portal/man/deal_sele_nonstand.Rd index 77e12e2..4bc920f 100644 --- a/kvfinder-web-portal/man/deal_sele_nonstand.Rd +++ b/kvfinder-web-portal/man/deal_sele_nonstand.Rd @@ -4,7 +4,13 @@ \alias{deal_sele_nonstand} \title{Process PDB file according to the selected non-standard residues} \usage{ -deal_sele_nonstand(pdb_input, nonstand_list, include_list, session = session) +deal_sele_nonstand( + input, + pdb_input, + nonstand_list, + include_list, + session = session +) } \arguments{ \item{pdb_input}{Pdb path} diff --git a/kvfinder-web-portal/man/report_nonstand.Rd b/kvfinder-web-portal/man/report_nonstand.Rd index d26d874..a0ce0b1 100644 --- a/kvfinder-web-portal/man/report_nonstand.Rd +++ b/kvfinder-web-portal/man/report_nonstand.Rd @@ -4,10 +4,12 @@ \alias{report_nonstand} \title{Get non-standard protein/nucleic residues} \usage{ -report_nonstand(pdb_input) +report_nonstand(pdb_input, show_modal) } \arguments{ \item{pdb_input}{Pdb path} + +\item{show_modal}{} } \description{ Get non standard protein/nucleic residues from PDB