From c0758e267385565b5d5e4c4d8798fd9691658efc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Todor=20Kondi=C4=87?= <todor.kondic@uni.lu> Date: Tue, 23 Aug 2022 14:16:36 +0200 Subject: [PATCH] app: Replaced qa_ms1[2] with qlt_ms1[2], changed how state is handled and fixed extract/prescreen stage in GUI. --- R/api.R | 1 + R/mix.R | 35 ++++++++++++----------- R/resources.R | 2 +- R/shiny-state.R | 28 ++++++++++-------- R/shiny-ui-base.R | 73 +++++++++++++++++++++++++---------------------- R/state.R | 17 +++++++++++ 6 files changed, 92 insertions(+), 64 deletions(-) diff --git a/R/api.R b/R/api.R index 12e8c48..f9c1059 100644 --- a/R/api.R +++ b/R/api.R @@ -139,6 +139,7 @@ load_data_input <- function(m) { m$input$tab$mzml <- as.data.table(m$input$tab$mzml) assert(all(unique(m$input$tab$mzml[,.N,by=c("adduct","tag")]$N)<=1),msg="Some rows in the data table contain multiple entries with same tag and adduct fields.") pref<-m$run$paths$data + message("load_data_input: ", pref) for (fn in m$input$tab$mzml$file) { if (!file.exists(file.path(pref,fn))) stop("File ",fn," does not exist.") } diff --git a/R/mix.R b/R/mix.R index 5d8ce29..5b2ef97 100644 --- a/R/mix.R +++ b/R/mix.R @@ -196,17 +196,17 @@ gen_summ <- function(comp,qa_ms1,qa_ms2) { data.table::setcolorder(summ,SUMM_COLS) ## Quality scores for ms1 and ms2. - summ[,qa_ms1 := as.integer(Map(function(m1,m2,m3) { m1*5L + m2*3L + m3*2L}, - as.integer(qa_ms1_exists), - as.integer(qa_ms1_above_noise), - as.integer(qa_ms1_good_int)))] - summ[,qa_ms2 := as.integer(Map(function(m1,m2,m3) { m1*5L + m2*3L + m3*2L}, - as.integer(qa_ms2_exists), - as.integer(qa_ms2_near), - as.integer(qa_ms2_good_int)))] - - summ[is.na(qa_ms1),qa_ms1:=0L] - summ[is.na(qa_ms2),qa_ms2:=0L] + summ[,qlt_ms1 := as.integer(Map(function(m1,m2,m3) { m1*5L + m2*3L + m3*2L}, + as.integer(qa_ms1_exists), + as.integer(qa_ms1_above_noise), + as.integer(qa_ms1_good_int)))] + summ[,qlt_ms2 := as.integer(Map(function(m1,m2,m3) { m1*5L + m2*3L + m3*2L}, + as.integer(qa_ms2_exists), + as.integer(qa_ms2_near), + as.integer(qa_ms2_good_int)))] + + summ[is.na(qlt_ms1),qlt_ms1:=0L] + summ[is.na(qlt_ms2),qlt_ms2:=0L] summ @@ -603,12 +603,13 @@ create_qa_table <- function(extr,conf_presc) { qa <- list(prescreen=conf_presc) - checks <- extr$ms2[,{ - z <-..QA_FLAGS - z[1:length(z)]<-F - names(z)<-..QA_FLAGS - z - },keyby=BASE_KEY_MS2] + ## checks <- extr$ms2[,{ + ## },keyby=BASE_KEY_MS2] + checks <- extr$ms2 + checks[,(QA_FLAGS):=F] + ## message("checks:") + ## print(checks) + ## message("done checks") checks[,(QA_NUM_INT):=NA_integer_] checks[,(QA_NUM_REAL):=NA_real_] setkeyv(checks,BASE_KEY_MS2) diff --git a/R/resources.R b/R/resources.R index 4c3b5d3..ffef246 100644 --- a/R/resources.R +++ b/R/resources.R @@ -284,7 +284,7 @@ SET_LIST_PATT <- CMPD_LIST_PATT DFILES_LIST_PATT <- ".*\\.mz[Mm][Ll]$" CINDEX_BY <- c("set","ID","adduct","tag") -CINDEX_COLS <- c("mz", "ms1_rt","Name","qa_ms1","qa_ms2") +CINDEX_COLS <- c("mz", "ms1_rt","Name","qlt_ms1","qlt_ms2") ARRANGE_CHOICES <- c(nothing="nothing", quality="quality", set="set", diff --git a/R/shiny-state.R b/R/shiny-state.R index c70cafd..16466b5 100644 --- a/R/shiny-state.R +++ b/R/shiny-state.R @@ -141,7 +141,7 @@ which_gui_radio_inputs <- function() { GUI_RADIO_INPUTS } -unpack_app_state <- function(session,input,project_path,packed_state) { +unpack_app_state <- function(session,input,top_data_dir,project_path,packed_state) { shiny::isolate({ for (inp in which_gui_select_inputs()) { shiny::updateSelectInput(session = session, @@ -174,7 +174,9 @@ unpack_app_state <- function(session,input,project_path,packed_state) { gui$datatab$adduct <- packed_state$datatab$adduct gui$datatab$tag <- packed_state$datatab$tag gui$datatab$set <- packed_state$datatab$set - gui$paths$data <- packed_state$paths$data + x <- packed_state$paths$data + gui$paths$data <- if (length(x)>0 & nchar(x)>0) file.path(top_data_dir,basename(x)) + if (!dir.exists(gui$paths$data)) {warning("Data directory ", gui$paths$data, " does not exist. You must select one.")} gui }) @@ -182,7 +184,6 @@ unpack_app_state <- function(session,input,project_path,packed_state) { } - input2conf_setup <- function(input,gui,conf=list()) { if (length(conf)==0L) { conf$compounds <- list() @@ -237,10 +238,13 @@ input2conf <- function(input,gui,conf=list()) { conf } -app_state2state <- function(input,gui) { - m <- new_project(gui$paths$project) +app_state2state <- function(input,gui,m=NULL) { + if (is.null(m)) m <- new_project(gui$paths$project) m$run$paths <- shiny::reactiveValuesToList(gui$paths) m$conf <- input2conf_setup(input,gui=gui) + m$conf <- input2conf_prescreen(input=input,conf=m$conf) + m$conf <- input2conf_figures(input,conf=m$conf) + m$conf <- input2conf_report(input,conf=m$conf) m$input$tab$mzml <- gui2datatab(gui) m } @@ -357,12 +361,12 @@ gen_cindex <- function(summ,sorder,cols = CINDEX_COLS,by. = CINDEX_BY) { allc <- c(by.,cols) xsumm <- summ[,..allc] setnames(xsumm,old="ms1_rt",new="rt",skip_absent=T) - res <- xsumm[,.SD[max(qa_ms1)==qa_ms1][max(qa_ms2)==qa_ms2],by=by.] - res <- res[,c("mz","rt","Name","qa_ms1","qa_ms2"):=.(first(mz), + res <- xsumm[,.SD[max(qlt_ms1)==qlt_ms1][max(qlt_ms2)==qlt_ms2],by=by.] + res <- res[,c("mz","rt","Name","qlt_ms1","qlt_ms2"):=.(first(mz), first(mean(rt)), first(Name), - first(qa_ms1), - first(qa_ms2)), + first(qlt_ms1), + first(qlt_ms2)), by=by.] res <- res[,unique(.SD),by=by.] @@ -372,12 +376,12 @@ gen_cindex <- function(summ,sorder,cols = CINDEX_COLS,by. = CINDEX_BY) { if (length(quality)>0L) { pre <- head(sorder,quality-1L) post <- tail(sorder,-quality) - sorder <- c(pre,"qa_ms1","qa_ms2",post) + sorder <- c(pre,"qlt_ms1","qlt_ms2",post) } ord <- rep(1L,length(sorder)) - if ("qa_ms1" %in% sorder) { - ind <- which(sorder %in% c("qa_ms1","qa_ms2")) + if ("qlt_ms1" %in% sorder) { + ind <- which(sorder %in% c("qlt_ms1","qlt_ms2")) ord[ind] <- -1L } if (length(sorder)>0) setorderv(res,cols=sorder,order=ord) diff --git a/R/shiny-ui-base.R b/R/shiny-ui-base.R index 6f2d168..d7a2b4a 100644 --- a/R/shiny-ui-base.R +++ b/R/shiny-ui-base.R @@ -722,6 +722,8 @@ mk_shinyscreen_server <- function(projects,init) { rvs$gui$datatab$tag rvs$gui$datatab$adduct rvs$gui$datatab$set + rvs$gui$paths$data + rvs$gui$paths$project isolate({ req(pre_setup_val_block(rvs$gui)) q = app_state2state(input,rvs$gui) @@ -730,16 +732,6 @@ mk_shinyscreen_server <- function(projects,init) { run(m=q,phases=c("setup","comptab")) }) - rf_get_cmpd_tab <- reactive({ - m <- rf_setup_state() - m$input$tab$cmpds - }) - - rf_get_sets_tab <- reactive({ - m <- rf_setup_state() - m$input$tab$setid - }) - rf_cindex_key <- reactive({ if (isTruthy(input$cindex_group)) setdiff(CINDEX_BY,input$cindex_group) else CINDEX_BY }) @@ -921,10 +913,17 @@ mk_shinyscreen_server <- function(projects,init) { pack <- readRDS(file=fn_packed_state) rvs$gui <- unpack_app_state(session=session, input=input, + top_data_dir=init$userdir, project_path=fullwd, packed_state=pack) ## Load computational state. rvs$m <- readRDS(file=fn_state) + rvs$m$run <- reinit_run_data(init$userdir, + project=rvs$gui$project(), + run = rvs$m$run) + + ## If prescreen config invalid, reinit. + if (length(rvs$m$conf$prescreen)==0) rvs$m$conf <- input2conf_prescreen(input=input,conf=rvs$m$conf) ## Update status variables. m <- rvs$m @@ -938,16 +937,20 @@ mk_shinyscreen_server <- function(projects,init) { rvs$status$ret_time_shift_tol_stat = rvs$m$conf$prescreen[["ret_time_shift_tol"]] if (NROW(m$extr$ms1)>0L) rvs$status$is_extracted_stat <- "Yes." if (NROW(m$out$tab$summ)>0L) rvs$status$is_qa_stat <- "Yes." + } else { message("Initialising project: ",wd) rvs$gui <- create_gui(project_path=fullwd) + + + } message("project: ",rvs$gui$project()) }, label = "project-b") observeEvent(input$extract_b,{ - rvs$m <-req(rf_setup_state()) + rvs$m <- app_state2state(input,rvs$gui,m=rvs$m) # Update params from GUI. m <- rvs$m shinymsg("Extraction has started. This may take a while.") rvs$status$ms1_coarse_stat = m$conf$tolerance[["ms1 coarse"]] @@ -966,7 +969,7 @@ mk_shinyscreen_server <- function(projects,init) { rv_extr_flag(F) m <-rvs$m - promises::future_promise(run(m=m,phases="extract")) %...>% { + promises::future_promise(run(m=m,phases=c("setup","comptab","extract"))) %...>% { rvs$m = . rvs$status$is_extracted_stat = "Yes." fn_c_state <- file.path(rvs$m$run$paths$project, @@ -1002,7 +1005,7 @@ mk_shinyscreen_server <- function(projects,init) { observeEvent(input$presc_b,{ if (NROW(rvs$m$extr$ms1)>0L) { - rvs$m$conf <- input2conf_prescreen(input=input,conf=rvs$m$conf) + rvs$m <- app_state2state(input,rvs$gui,m=rvs$m) # Update params from GUI. rvs$status$ms1_int_thresh_stat = rvs$m$conf$prescreen[["ms1_int_thresh"]] rvs$status$ms2_int_thresh_stat = rvs$m$conf$prescreen[["ms2_int_thresh"]] rvs$status$s2n_stat = rvs$m$conf$prescreen[["s2n"]] @@ -1265,29 +1268,31 @@ mk_shinyscreen_server <- function(projects,init) { }) output$comp_table <- DT::renderDataTable({ - cmpds <- rf_get_cmpd_tab() - validate(need(NROW(cmpds)>0,"No compound list loaded yet.")) - DT::datatable(cmpds, - ## style = 'bootstrap', - ## class = 'table-condensed', - extensions = 'Scroller', - options = list(scrollX = T, - scrollY = 300, - deferRender = T, - scroller = T)) + ## TODO FIXME + ## cmpds <- rf_get_cmpd_tab() + ## validate(need(NROW(cmpds)>0,"No compound list loaded yet.")) + ## DT::datatable(cmpds, + ## ## style = 'bootstrap', + ## ## class = 'table-condensed', + ## extensions = 'Scroller', + ## options = list(scrollX = T, + ## scrollY = 300, + ## deferRender = T, + ## scroller = T)) }) output$setid_table <- DT::renderDataTable({ - setid <- rf_get_sets_tab() - validate(need(NROW(setid)>0,"No set id list loaded yet.")) - DT::datatable(setid, - ## style = 'bootstrap', - ## class = 'table-condensed', - extensions = 'Scroller', - options = list(scrollX = T, - scrollY = 300, - deferRender = T, - scroller = T)) + ## TODO FIXME + ## setid <- rf_get_sets_tab() + ## validate(need(NROW(setid)>0,"No set id list loaded yet.")) + ## DT::datatable(setid, + ## ## style = 'bootstrap', + ## ## class = 'table-condensed', + ## extensions = 'Scroller', + ## options = list(scrollX = T, + ## scrollY = 300, + ## deferRender = T, + ## scroller = T)) }) ## RENDER: STATUS @@ -1875,7 +1880,7 @@ mk_shinyscreen_server <- function(projects,init) { } if (NROW(rv_tran$qa_ms2sel_tab)>0) { - qa_names <- c("ms2_sel",colnames(flt_summ)[grepl("qa_ms2",colnames(flt_summ))]) + qa_names <- c("ms2_sel",colnames(flt_summ)[grepl("qlt_ms2",colnames(flt_summ))]) qatab <- copy(rv_tran$qa_ms2sel_tab) qatab[,(qa_names):=lapply(.SD,yesno2log),.SDcol=qa_names] entries <- cbind(compsel[the_row][,.(adduct,tag,ID)], diff --git a/R/state.R b/R/state.R index e9b3231..aebe8f4 100644 --- a/R/state.R +++ b/R/state.R @@ -40,6 +40,19 @@ runtime_from_conf <- function(run,conf) { run } +reinit_run_data <- function(userdir,project,run) { + olddata <- run$paths$data + oldproject <- basename(run$paths$project) + if (project != oldproject) { + message("Project has been renamed to: ",project) + message("Old project name was: ", oldproject) + } + if (isTruthy(olddata)) run$paths$data <- file.path(userdir,basename(olddata)) + run$project <- project + run$paths$project <- file.path(userdir,project) + run +} + ## This helps decouple "cross-platform" configuration from the ## (file-)system dependent facts. @@ -110,6 +123,10 @@ refresh_state <- function(m) { new_rv_state <- function() react_v(m=list2rev(new_state())) + + + + write_conf <- function(m,fn) { m$conf$paths$data <- get_fn_ftab(m) if (NROW(m$input$tab$mzml)>0) tab2file(tab=m$input$tab$mzml,file=file.path(m$run$paths$project,FN_DATA_TAB)) -- GitLab