Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • eci/shinyscreen
  • miroslav.kratochvil/shinyscreen
2 results
Show changes
Commits on Source (47)
Package: shinyscreen
Title: Pre-screening of Mass Spectrometry Data
Version: 0.8
Version: 0.9.0
Author: Todor Kondić
Maintainer: Todor Kondić <todor.kondic@uni.lu>
Authors@R:
......@@ -29,7 +29,7 @@ Description: Pre-screening of Mass Spectrometry Data.
License: Apache License (>= 2.0)
Encoding: UTF-8
LazyData: true
RoxygenNote: 6.1.1
RoxygenNote: 7.1.0
Roxygen: list(markdown = TRUE)
Collate:
'resources.R'
......@@ -37,7 +37,10 @@ Collate:
'mix.R'
'extraction.R'
'run.R'
'shinyUI.R'
'api.R'
'shiny-ui-base.R'
'shiny-ui-config.R'
'shiny-ui-top.R'
Depends:
RMassBank,
RChemMass
......@@ -48,6 +51,9 @@ Imports:
yaml,
mzR,
MSnbase,
data.table,
assertthat,
withr,
ggplot2,
cowplot,
RColorBrewer,
......
# Generated by roxygen2: do not edit by hand
export(gen)
export(gen_base_ftab)
export(launch)
export(load_inputs)
export(mk_comp_tab)
export(read_conf)
export(run)
export(run_in_dir)
export(vrfy_conf)
import(data.table)
importFrom("(shiny,","validate)")
## Copyright (C) 2020 by University of Luxembourg
## Licensed under the Apache License, Version 2.0 (the "License");
## you may not use this file except in compliance with the License.
## You may obtain a copy of the License at
## http://www.apache.org/licenses/LICENSE-2.0
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##' @export
run <- function(fn_conf) {
conf <- read_conf(fn_conf)
dir.create(conf$project,
showWarnings = F,
recursive = T)
withr::with_dir(new=conf$project,code = run_in_dir(conf))
return()
}
##' @export
run_in_dir <- function(conf) {
m <- load_inputs(conf)
m <- mk_comp_tab(m)
m <- gen_base_tab(m)
stop()
m
}
##' @export
gen_base_ftab <- function(m) {
files <- add_wd_to_mzml(df=m$input$tab$mzml,wdir=m$conf$project)
df <- gen_sup_ftab(files,m$out$tab$comp)
tab2file(df,file.path(m$conf$project,FN_FTAB_BASE))
m$out$tab$ftab <- df
}
##' @export
load_inputs <- function(conf) {
m<-list()
m$conf <- conf
m$input$tab$mzml <- file2tab(m$conf$data)
m$input$tab$known <- if (shiny::isTruthy(m$input$tab$known))
file2tab(m$conf$compounds$known) else EMPTY_KNOWN
m$input$tab$unknown <- if (shiny::isTruthy(m$input$tab$unknown))
file2tab(m$conf$compounds$unknown) else EMPTY_UNK
m$input$tab$setid <- read_setid(m$conf$compounds$sets,
m$input$tab$known,
m$input$tab$unknown)
m
}
##' @export
mk_comp_tab <- function(m) {
message("Started assembling the lists of knowns and unknowns into the `comprehensive' table.")
setid <- m$input$tab$setid
setkey(setid,set,ID)
mzml<- m$input$tab$mzml
setkey(mzml,set)
unk<-m$input$tab$unknown
setkey(unk,ID)
known<-m$input$tab$known
setkey(known,ID)
assertthat::assert_that(xor(nrow(unk)==0,nrow(known)==0),msg="No compound lists have been provided. At least one of the known, or unknown compound lists is required.")
message("Begin generation of comp table.")
## knowns
setidKnown<- merge(mzml[,.(mode,set)],setid[origin=="known",],allow.cartesian = T)
compKnown <- setidKnown[known,on="ID"]
compKnown[,`:=`(mz=mapply(get_mz_from_smiles,SMILES,mode,USE.NAMES = F))]
message("Generation of comp table: knowns done.")
## unknows
setidUnk<-merge(mzml[,.(mode,set)],setid[origin=="unknown",],allow.cartesian = T)
compUnk <- setidUnk[unk,on="ID"]
message("Generation of comp table: unknowns done.")
df<-rbindlist(l=list(compKnown, compUnk),fill = T)
setnames(df,names(COMP_NAME_MAP),
function(o) COMP_NAME_MAP[[o]])
fn_out <- file.path(m$conf$project,FN_COMP_TAB)
tab2file(tab=df,file=fn_out)
message("Generation of comp table finished.")
setkeyv(df,c("set","tag","mz"))
m$out$tab$comp <- df
m
}
##' @export
read_conf <- function(fn_conf) {
assertthat::assert_that(file.exists(fn_conf),msg=paste("Unable to read the configuration file:", fn_conf))
conf <- yaml::yaml.load_file(fn_conf)
conf <- vrfy_conf(conf)
conf
}
##' @export
vrfy_conf <- function(conf) {
## * Existence of input files
fn_cmpd_known <- conf$compounds$known
fn_cmpd_unk <- conf$compounds$unknown
fn_cmpd_sets <- conf$compounds$sets
## ** Compound lists and sets
assertthat::assert_that(file.exists(fn_cmpd_sets),
msg=paste("Cannot find the compound sets file:",fn_cmpd_sets))
if (!is.null(fn_cmpd_known)) assertthat::assert_that(file.exists(fn_cmpd_known),
msg=paste("Cannot find known compounds file:",fn_cmpd_known))
if (!is.null(fn_cmpd_unk)) assertthat::assert_that(file.exists(fn_cmpd_unk),
msg=paste("Cannot find unknown compounds file:",fn_cmpd_unk))
## * Data files
df_sets <- file2tab(fn_cmpd_sets)
all_sets<-unique(df_sets$set)
fn_data <- conf$data
assertthat::assert_that(file.exists(fn_data),msg=paste("Data table does not exist:",fn_data))
mzml <- file2tab(fn_data)
no_files <- which(mzml[,!file.exists(Files)])
no_modes <- which(mzml[,!(mode %in% names(MODEMAP))])
no_sets <- which(mzml[,!(set %in% all_sets)])
assertthat::assert_that(length(no_files)==0,msg = paste("Non-existent data files at rows:",paste(no_files,collapse = ','), "of",fn_data))
assertthat::assert_that(length(no_modes)==0,msg = paste("Unrecognised modes at rows:",paste(no_modes,collapse = ','), "of", fn_data))
assertthat::assert_that(length(no_sets)==0,msg = paste("Unknown sets at rows:",paste(no_sets,collapse = ','),"of", fn_data))
df_k <- file2tab(fn_cmpd_known)
are_knowns_OK <- shiny::isTruthy(vald_comp_tab(df_k,fn_cmpd_known, checkSMILES=T, checkNames=T))
assertthat::assert_that(are_knowns_OK)
## ** Unknowns
if (!is.null(fn_cmpd_unk)) {
df_u <- file2tab(fn_cmpd_unk)
are_unknowns_OK <- shiny::isTruthy(vald_comp_tab(df_u,fn_cmpd_unk, checkSMILES=F, checkMz=T))
assertthat::assert_that(are_unknowns_OK)
}
return(conf)
}
......@@ -12,16 +12,18 @@
## See the License for the specific language governing permissions and
## limitations under the License.
##' @import data.table
## Redirections
the_ifelse <- data.table::fifelse
dtable <- data.table::data.table
tab2file<-function(tab,file,...) {
write.csv(x=tab,file=file,row.names=F,...)
data.table::fwrite(x=tab,file=file,...)
}
file2tab<-function(file,stringsAsFactors=F,comment.char='',sep=',',...) {
read.csv(file=file,
header=T,
stringsAsFactors=stringsAsFactors,
comment.char=comment.char,
na.strings=c("","NA"),...)
file2tab<-function(file,na.strings=c("","NA"),...) {
data.table::fread(file=file,na.strings = na.strings, ...)
}
isThingFile<-function(fn) {
......@@ -30,3 +32,13 @@ isThingFile<-function(fn) {
} else F
}
## Stolen from Stack Overflow
split_path <- function(path) {
if (dirname(path) %in% c(".", path)) return(basename(path))
return(c(basename(path), split_path(dirname(path))))
}
print_table <- function (df) {
paste(apply(df,1,function (row) paste(row,collapse=',')),collapse = "\n")
}
......@@ -267,20 +267,6 @@ gen_ms1_chrom_ht<-function(raw,mz,errEIC,rt=NULL,errRT=NULL) {
res
}
tab2file<-function(tab,file,...) {
write.csv(x=tab,file=file,row.names=F,...)
}
file2tab<-function(file,stringsAsFactors=F,comment.char='',...) {
read.csv(file=file,
header=T,
stringsAsFactors=stringsAsFactors,
comment.char=comment.char,
na.strings=c("","NA"),...)
}
get_ext_width <- function(maxid) {as.integer(log10(maxid)+1)}
id_fn_ext<-function(width,id) {
formatC(as.numeric(id),width=width,flag=0)
......
......@@ -31,6 +31,10 @@ get_mz_cmp_l<-function(id,mode,cmpL) {
res
}
get_mz_from_smiles <- function(smiles,mode) {
RChemMass::getSuspectFormulaMass(smiles)[[MODEMAP[[mode]]]]
}
get_col_from_cmp_l<-function(id,cname,cmpL) {
ind<-match(id,cmpL$ID)
x<-cmpL[[cname]][[ind]]
......@@ -53,7 +57,7 @@ pp_touch_q<-function(ftab) {
which(ftab$checked==FTAB_CHK_NONE | ftab$checked==FTAB_CHK_AUTO)
}
preProc <- function (ftable,noiseFac=3,errRT=0.5,intThreshMS1=1e5,intThreshMS2=0.05) {
preProc <- function (ftable,noiseFac=3,errRT=0.5,intThreshMS1=1e5,intThreshMS2=5000.) {
wds<-unique(ftable$wd)
fn_spec<-function(wd) readRDS(file.path(wd,FN_SPEC))
message("Loading RDS-es ...")
......@@ -145,7 +149,7 @@ preProc <- function (ftable,noiseFac=3,errRT=0.5,intThreshMS1=1e5,intThreshMS2=0
eicFilt<- eic[rtIndMS1,]
eicFilt<- eicFilt[which(eicFilt$intensity>intThreshMS1),]
mInt<- maxInt #mean(eicFilt$intensity)
rtInd <- rtInd[which(msms$intensity[rtInd]>intThreshMS2*mInt)] #Intense enough?
rtInd <- rtInd[which(msms$intensity[rtInd]>intThreshMS2)] #Intense enough?
msmsRT <- msms$rt[rtInd]
msmsInt<- msms$intensity[rtInd]
if (length(msmsRT) > 0) {
......@@ -449,7 +453,7 @@ plot_id_msn <- function(ni,
adornmzMLTab<-function(df,projDir=getwd()) {
add_wd_to_mzml <- function(df,wdir) {
pref<-df$set
mask<-is.na(pref)
drop<-df$files[mask]
......@@ -457,36 +461,16 @@ adornmzMLTab<-function(df,projDir=getwd()) {
df<-df[!mask,]
pref<-df$set
wd<-basename(tools::file_path_sans_ext(df$Files))
wd<-file.path(projDir,pref,wd)
wd<-file.path(wdir,pref,wd)
df$wd<-wd
df
}
genSuprFileTab <- function(fileTab,compTab) {
genOne<-function(ids,fn) {
K<-length(ids)
fTabRow<-fileTab[fileTab$Files == fn,]
cols<-lapply(names(fileTab),function(n) rep(fTabRow[[n]],K))
names(cols)<-NULL
cols<-c(cols,list(ids))
names(cols)<-c(names(fileTab),"ID")
df<-as.data.frame(cols,stringsAsFactors = F)
df
}
tabs<-lapply(fileTab$Files,function(fn)
{
wh<-which(fileTab$Files==fn)
set<-fileTab$set[[wh]]
md<-fileTab$mode[[wh]]
sel<-(compTab$set %in% set) & (compTab$mode %in% md)
ids<-compTab$ID[sel]
genOne(ids,fn)
})
res<-do.call(rbind,tabs)
res
gen_sup_ftab <- function(ftab,ctab) {
df<-ctab[ftab,on=c("set","mode"),allow.cartesian=T]
setkeyv(df,cols=FTAB_KEY)
setcolorder(df,neworder = FTAB_NAMES)
df
}
getEntryFromComp<-function(entry,id,set,mode,compTab) {
......@@ -496,9 +480,13 @@ getEntryFromComp<-function(entry,id,set,mode,compTab) {
res<- if (length(ind)==1) compTab[ind,entry] else {
if (length(ind)>1) {
stop("Nonunique entry selection in comprehensive table.")
warning("Nonunique selection in comprehensive table:")
for (i in ind) {
message('ID: ',compTab$ID[[i]],' set: ',compTab$set[[i]],' mode: ',compTab$mode[[i]])
}
warning("The compound set table likely containes duplicate IDs per set/mode combination. Please correct this.")
} else {
stop("Entries not found for id ", id,"set ",set, "and mode ", mode, " .")
warning("Entries not found for id ", id,"set ",set, "and mode ", mode, " .")
}
}
res
......@@ -506,29 +494,32 @@ getEntryFromComp<-function(entry,id,set,mode,compTab) {
res
}
addCompColsToFileTbl<-function(ft,compTab) {
nR<-nrow(ft)
mzCol<-rep(NA,nR)
nmCol<-rep("",nR)
rtCol<-rep(NA,nR)
## add_comp_ftab <- function(ft,ctab) {
## nR<-nrow(ft)
## mzCol<-rep(NA,nR)
## nmCol<-rep("",nR)
## rtCol<-rep(NA,nR)
for (ir in 1:nR) {
id<-ft[ir,"ID"]
set<-ft[ir,"set"]
m<-ft[ir,"mode"]
entries<-getEntryFromComp(c("mz","Name","rt"),id,set,m,compTab)
mzCol[[ir]]<- entries[["mz"]]
nm<-entries[["Name"]]
nmCol[[ir]]<- if (!is.na(nm)) nm else ""
rtCol[[ir]]<- entries[["rt"]]
}
ft$mz<-mzCol
ft$Name<-nmCol
ft$rt<-rtCol
ft
## for (ir in 1:nR) {
## id<-ft[ir,"ID"]
## set<-ft[ir,"set"]
## m<-ft[ir,"mode"]
## entries<-getEntryFromComp(c("mz","Name","rt"),id,set,m,ctab)
## mzCol[[ir]]<- entries[["mz"]]
## nm<-entries[["Name"]]
## nmCol[[ir]]<- if (!is.na(nm)) nm else ""
## rtCol[[ir]]<- entries[["rt"]]
## }
## ft$mz<-mzCol
## ft$Name<-nmCol
## ft$rt<-rtCol
## ft
## }
get_set_mode <- function(s,mzml) {
unique(mzml[set == s,mode])
}
vald_comp_tab<-function(df,ndf,checkSMILES=F,checkMz=F,checkNames=F) {
## Fields.
if (is.null(df$ID)) stop("Column ID missing in ",ndf," .")
......@@ -574,7 +565,6 @@ vald_comp_tab<-function(df,ndf,checkSMILES=F,checkMz=F,checkNames=F) {
ll<-length(unique(df$SMILES))
if (ll<lsmiles) {
warning("There are duplicate SMILES in the compound list. Trouble ahead.")
return(NULL)
}
}
......@@ -591,3 +581,23 @@ vald_comp_tab<-function(df,ndf,checkSMILES=F,checkMz=F,checkNames=F) {
df
}
read_setid <- function(fn,known,unk) {
setid <- file2tab(fn)
id_k <- known$ID
id_u <- unk$ID
tmp <- setid[,.(ID,set,origin=the_ifelse(ID %in% id_k,"known",NA_character_))]
tmp <- tmp[,.(ID,set,origin=the_ifelse(is.na(origin) & ID %in% id_u,"unknown",origin))]
natmp <- tmp[is.na(origin),.(ID,set)]
assertthat::assert_that(nrow(natmp)==0,msg=paste("The following IDs from set table have not been found in the compound table:","------",print_table(natmp),"------",sep = "\n"))
tmp
}
write_conf <- function(conf,fn) {
yaml::write_yaml(x=conf,file=fn)
}
read_conf <- function(fn) {
yaml::yaml.load_file(fn)
}
......@@ -14,6 +14,14 @@
## Config defaults
CONF <- list(data=NA_character_,
project=getwd(),
compounds=list(known=NA_character_,
unknown=NA_character_,
sets=NA_character_))
## Constants
FN_FTAB_BASE<-"ftable.base.csv"
FN_FTAB_PP<-"ftable.pp.csv"
......@@ -24,12 +32,12 @@ FN_CMP_L<-"compounds.csv"
FN_LOC_SETID <-"setid.csv"
FN_COMP_TAB<-"comprehensive.csv"
FN_SPEC<-"specdata.rds"
MODEMAP<-list(pH="MpHp_mass",
mH="MmHm_mass",
pNH4="MpNH4_mass",
pNa="MpNa_mass")
MODEMAP<-list("[M+H]+"="MpHp_mass",
"[M-H]-"="MmHm_mass",
"[M+NH4]+"="MpNH4_mass",
"[M+Na]+"="MpNa_mass")
TAG_DEF<-"unspecified"
TAG_DEF <- "unspecified"
TAG_DEF_DESC<-"Case"
DEFAULT_RT_RANGE=c(NA,NA)
DEFAULT_INT_RANGE=c(NA,NA)
......@@ -90,7 +98,7 @@ RT_EXTR_ERR<-0.5 # min
RT_SHIFT_ERR <- 0.5 # min
MS1_INT_THOLD <- 1e5
MS2_INT_THOLD <- 0.05
MS2_INT_THOLD <- 5000.
MS1_SN_FAC <- 3.0
......@@ -98,3 +106,15 @@ MS1_SN_FAC <- 3.0
## Shiny objects
NUM_INP_WIDTH="15%"
## Comprehensive table properties
COMP_NAME_MAP <- list(RT="rt")
# COMP_NAMES <-c("ID","mz","rt","mode","set","origin","Name","SMILES")
## File table properties
FTAB_KEY=c("set","tag","mz")
FTAB_NAMES=c("ID", "mz", "rt", "tag", "mode", "set", "Name", "SMILES", "Files" , "wd","origin")
EMPTY_UNK <- data.table(ID=character(0),mz=numeric(0),RT=numeric(0),Name=character(0),CAS=character(0))
EMPTY_KNOWN <- data.table(ID=character(0),SMILES=character(0),RT=numeric(0),Name=character(0),CAS=character(0))
## Copyright (C) 2020 by University of Luxembourg
## Licensed under the Apache License, Version 2.0 (the "License");
## you may not use this file except in compliance with the License.
## You may obtain a copy of the License at
## http://www.apache.org/licenses/LICENSE-2.0
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##' @importFrom(shiny, validate)
react_v <- shiny::reactiveValues
react_f <- shiny::reactive
react_e <- shiny::eventReactive
obsrv <- shiny::observe
obsrv_e <- shiny::observeEvent
vols <- shinyFiles::getVolumes
vol_f <- vols()
validate1 <- function(expr,msg) shiny::validate(need(expr,msg))
path2vol <- function(path) {
## This function returns shinyFiles compatible volumes.
splits <- split_path(path)
file.path(tail(splits,1),'')
}
prim_box<-function(...) {shinydashboard::box(...,
status="primary",
solidHeader=T)}
good_box<-function(...) {shinydashboard::box(...,
status="success",
solidHeader=T)}
err_box<-function(...) {shinydashboard::box(...,
status="danger",
solidHeader=T)}
inact_box<-function(...) {shinydashboard::box(...,
status="danger",
solidHeader=T)}
html<-function(...) {shiny::tags$div(shiny::HTML(...))}
## num_input<-function(...,width=NUM_INP_WIDTH) {shiny::tags$div(id="inline",shiny::textInput(...,width=width))}
num_input <- function(inputId,label,...,width=NUM_INP_WIDTH) {
shiny::tags$div(style="display:inline-block",
shiny::tags$label(label, `for` = inputId),
shiny::tags$input(id = inputId, type = "text",style=paste("width:",width,sep = ""),...))
}
num_input_unit <- function(inputId,l1,l2,width=NUM_INP_WIDTH,...) {
shiny::tags$div(style="display:inline-block",
shiny::tags$label(l1, `for` = inputId),
shiny::tags$input(id = inputId, type = "text",style=paste("width:",width,sep = ""),...),
shiny::tags$label(paste(" ",l2,sep=""), `for` = inputId))
}
txt_file_input <- function(inputId,input,fileB,label,volumes) {
fnobj<-shinyFiles::parseFilePaths(roots = volumes,
selection = input[[fileB]])
fn <- fnobj[['datapath']]
if (isThingFile(fn)) {
shiny::textInput(inputId = inputId,
label = label,
value = fn)
} else {
shiny::isolate(currFn <- input[[inputId]])
if (!isThingFile(currFn)) {
shiny::textInput(inputId = inputId,
label = label,
value = "")
} else {
message('Why is this happening so much?')
shiny::textInput(inputId = inputId,
label = label,
value = currFn)
}
}
}
rv_conf2conf <- function(rv) {
x <- shiny::reactiveValuesToList(rv$conf)
x$compounds<-shiny::reactiveValuesToList(rv$conf$compounds)
x
}
conf2rv_conf <- function(conf,rv) {
rv$conf <- shiny::reactiveValues(project=conf$project,
data=conf$data,
compounds=shiny::reactiveValues(known=conf$compounds$known,
unknown=conf$compounds$unknown,
setid=conf$compounds$setid))
rv
}
## Copyright (C) 2020 by University of Luxembourg
## Licensed under the Apache License, Version 2.0 (the "License");
## you may not use this file except in compliance with the License.
## You may obtain a copy of the License at
## http://www.apache.org/licenses/LICENSE-2.0
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## Commentary:
##
## Defines config tab.
mk_ui_config <- function() {
browseFile <- function(title,
buttonName,
txtName,
buttonTxt="Import compound list.",
txtTxt="",
icon="file",
description=NULL,
...) {
prim_box(title=title,
shiny::h5(description),
collapsible=F,...)}
confImport <- prim_box(title="Import",
shiny::uiOutput("fnKnownLCtrl"),
shiny::uiOutput("fnUnkLCtrl"),
shiny::uiOutput("fnSetIdCtrl"),
shinyFiles::shinyFilesButton("impKnownListB",
label="Import knowns.",
title="",
icon=shiny::icon("file"),
multiple=F),
shinyFiles::shinyFilesButton("impUnkListB",
label="Import unknowns.",
title="",
icon=shiny::icon("file"),
multiple=F),
shinyFiles::shinyFilesButton("impSetIdB",
label="Import set ID table.",
title="",
icon=shiny::icon("file"),
multiple=T),
width=NULL)
confmzMLTags <- prim_box(title="Tags",
shiny::textInput("tagPropInp",
"What is a tag? (optional)",
value=TAG_DEF_DESC),
shiny::textInput("tagsInp",
"Comma-delimited list of tag types.",
value=""),
shiny::actionButton("updTagsB",
label = "Update tags.",
icon=shiny::icon("bomb")),
width=NULL)
confState <- prim_box(title="Configuration State",
shinyFiles::shinySaveButton("saveConfB",
"Save configuration.",
title="Save",
filename = "conf-state.yaml",
"yaml"),
shinyFiles::shinyFilesButton("restoreConfB",
label="Restore configuration.",
multiple=F,
title="Restore"),
shiny::actionButton(inputId="resetConfB",
label="Reset config (CAUTION!)",
icon=shiny::icon("trash")),
width=NULL)
confProj <- prim_box(title="Project",
shinyFiles::shinyDirButton(id="switchProjB",
label="Switch project.",
title="Switch project.",
icon=shiny::icon("recycle")),
width=NULL)
confmzMLtab <-prim_box(title="Raw Files in mzML Format",
shiny::h5("Use this file table to assign adduct modes and tags to the data files."),
shinyFiles::shinyFilesButton("mzMLB",
label="Select mzML files",
title="Select mzML files",
icon=shiny::icon("files-o"),
multiple=T),
rhandsontable::rHandsontableOutput("mzMLtabCtrl"),
width=NULL)
confLayout <- shiny::fluidRow(shiny::column(confImport,
confmzMLTags,
confState,
confProj,
width=4),
shiny::column(width=8,
confmzMLtab))
confTab <- shinydashboard::tabItem(tabName="config",
shiny::h2(GUI_TAB_TITLE[["conf"]]),
confLayout)
confSideItem <- shinydashboard::menuItem(text=GUI_SIDE_TITLE[["conf"]],
tabName="config",
icon=shiny::icon("user-cog"))
return(list(tab=confTab,
side=confSideItem))
}
react_conf_v <- function(input,output,session,rv,rf) {
rv$conf <- react_v(data=CONF$data,
project=CONF$project,
compounds=react_v(known=CONF$compounds$known,
unknown=CONF$compounds$unknown,
sets=CONF$compounds$sets))
rv
}
react_conf_f <- function(input,output,session,rv,rf) {
rf$get_proj_vol <- react_e(rv$conf$project,{
## For shinyfiles dialogs.
path <- normalizePath(rv$conf$project, winslash = '/')
vls <- vols()() #Ugly! :)
vol <- path2vol(path)
sel<-match(vol,vls)
validate(sel,msg="Yikes! Unable to detect current project's volume.")
res<-names(vls)[[sel]]
res
})
rf$get_proj_path <- react_e(rv$conf$project,{
## For shinyfiles dialogs.
wd <- rv$conf$project
vol <- rf$get_proj_vol()
v <- vols()()
pref<-v[[vol]]
res<-wd
message('Relative project path is: ',res)
res
})
rf
}
server_conf <- function(input,output,session,rv,rf) {
## ***** shinyFiles observers *****
droot <- rf$get_proj_vol
dpath <- rf$get_proj_path
vs <- vols()
shinyFiles::shinyFileChoose(input, 'impKnownListB',defaultRoot=droot(),
defaultPath=dpath(),roots=vs)
shinyFiles::shinyFileChoose(input, 'impUnkListB',defaultRoot=droot(),
defaultPath=dpath(),roots=vs)
shinyFiles::shinyFileChoose(input, 'impSetIdB',defaultRoot=droot(),
defaultPath=dpath(),roots=vs)
shinyFiles::shinyFileSave(input, 'saveConfB',defaultRoot=droot(),
defaultPath=dpath(),roots=vs)
shinyFiles::shinyFileChoose(input, 'restoreConfB',defaultRoot=droot(),
defaultPath=dpath(),roots=vs)
shinyFiles::shinyFileChoose(input, 'mzMLB',defaultRoot=droot(),
defaultPath=dpath(),roots=vs)
shinyFiles::shinyDirChoose(input, 'switchProjB',roots=vs)
obsrv_e(input$saveConfB, {
conf<-rv_conf2conf(rv)
vol <- vol_f()
fn <- shinyFiles::parseSavePath(roots=vol_f,input$saveConfB)[["datapath"]]
validate(fn,msg="Invalid file to save config to.")
write_conf(conf,fn)
})
obsrv_e(input$restoreConfB,{
fn <- shinyFiles::parseSavePath(roots=vol_f,input$saveConfB)[["datapath"]]
validate(fn,msg="Something went wrong with the config file name.")
validate(file.exists(fn),msg="The file is unreadable.")
conf <- read_conf(fn)
rv <- vonf2rv_conf(conf,rv)
})
obsrv_e(rv$conf,message("updated rv"))
rv
}
## Copyright (C) 2020 by University of Luxembourg
## Licensed under the Apache License, Version 2.0 (the "License");
## you may not use this file except in compliance with the License.
## You may obtain a copy of the License at
## http://www.apache.org/licenses/LICENSE-2.0
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## Commentary:
##
## This is a top-level Shiny file to bind them all.
mk_ui <- function (fn_style) {
## Top-level UI function.
headerText <- "Shinyscreen"
header <- shinydashboard::dashboardHeader(title=headerText,
shinydashboard::dropdownMenuOutput("notify"))
## Plugins
conf <- mk_ui_config()
sidebar <- shinydashboard::dashboardSidebar(shinydashboard::sidebarMenu(id='tabs',
conf$side,
shiny::hr(),
shiny::h5("Inputs"),
shiny::hr()))
body <- shinydashboard::dashboardBody(
shiny::tags$head(shiny::tags$style(shiny::includeHTML(fn_style))),
shinydashboard::tabItems(conf$tab))
shinydashboard::dashboardPage(
header,
sidebar,
body)
}
mk_shinyscreen <- function(fn_style=system.file('www/custom.css',package = 'shinyscreen')) {
server <- function(input,output,session) {
## Top-level server function.
rv <- shiny::reactiveValues(dummy=1) # Container for all
# reactive values.
rf <- list() # Container for all
# reactive functions.
rv <- react_conf_v(input,output,session,rv=rv,rf=rf) # Config related r. values.
rf <- react_conf_f(input,output,session,rv=rv,rf=rf) # Config related r. functions.
## Observers and renderers.
rv <- server_conf(input,output,session,rv=rv,rf=rf)
session$onSessionEnded(function () {
stopApp()
})
}
shiny::shinyApp(ui=mk_ui(fn_style=fn_style),server=server)
}
##' @export
launch <- function(GUI=T,fn_conf="",...) {
if (GUI) {
app<-mk_shinyscreen()
shiny::runApp(appDir = app,...)
} else {
if (nchar(fnConf)==0) {
fn_conf <- commandArgs(trailingOnly=T)[[1]]
}
run(fn_conf)
}
}
This diff is collapsed.
......@@ -253,12 +253,37 @@
In addition, the IDs of compounds belonging to the same set/mode
combination must be unique. Different ID sets may overlap.
Essentially, sets serve the purpouse of visually grouping files in
the plots. Also, set combines those groups of files with particular
collections of compounds (from the compound set CSV file).
** Config Screen
This is the start tab. Import the compound and set lists first,
then proceed to import the mzML files. Provide tags in the tag text
box and then assign the sets, modes and tags to the imported mzML
files using table widget. Once this is done, move on to the
`Spectra Extraction' tab.
~Spectra Extraction~ tab.
*** Resetting State
In case some inputs have been changed, but the program for some
reason does not seem to respond to those changes, perhaps
resetting the state using the button ~Reset State~ will help. This
will clean the current compound state tables (but, all the inputs
remain unchanged).
*** Switching Projects
The ~Switch project.~ button can be used to start new projects, or
change between them in the middle of processing.
Switching projects while the program is running makes most sense
if it is desired to change some of the inputs (e.g. different set
configuration, or same compound lists but different files) while
retaining the others. The user is presented with a directory
change dialogue which is then used to select the new project
directory. If needed, a new project directory can be created from
the same dialogue. All the inputs that currently exist on the
configuration tab will be kept during switching. This way, only
what needs to be changed can be changed.
** Spectra Extraction
Set the extraction parameters and then select a certain number of
......
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mix.R
\name{RMB_EIC_prescreen_df}
\alias{RMB_EIC_prescreen_df}
\title{Prescreen}
\usage{
RMB_EIC_prescreen_df(wd, RMB_mode, FileList, cmpd_list,
ppm_limit_fine = 10, EIC_limit = 0.001)
}
\arguments{
\item{wd}{Absolute path to the directory that will contain the
resulting data frame.}
\item{RMB_mode}{...}
\item{FileList}{...}
\item{cmpd_list}{...}
\item{ppm_limit_fine}{...}
\item{EIC_limit}{...}
}
\description{
Prescreens. Writes data out. Adapted from ReSOLUTION
}
\author{
Emma Schymanski, Todor Kondić
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mix.R
\name{gen_cmpd_l}
\alias{gen_cmpd_l}
\title{Generate Compound List File}
\usage{
gen_cmpd_l(src_fn, dest_fn)
}
\arguments{
\item{src_fn}{The input compound list CSV filename.}
\item{dest_fn}{The resulting compound list CSV filename.}
}
\value{
Number of compounds.
}
\description{
Generate the RMassBank compound list from the input compound list
in CSV file src_fn. The input compound list format is either a
Chemical Dashboard csv file with, at least, PREFERRED_ SMILES
columns \emph{filled} out, or just an ordinary CSV file with columns
SMILES and Names filled. Argument dest_fn is the destination
filename. Returns the number of compounds.
}
\author{
Todor Kondić
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mix.R
\name{gen_cmpdl_and_load}
\alias{gen_cmpdl_and_load}
\title{Generate and Load the RMassBank Compound List}
\usage{
gen_cmpdl_and_load(wd, fn_cmpdl)
}
\arguments{
\item{wd}{Directory under which results are archived.}
\item{fn_cmpdl}{The input compound list filename.}
}
\value{
Named list. The key \code{fn_cmpdl} is the path of the
generated compound list and the key \code{n} the number of
compounds.
}
\description{
Generates the RMassBank compound list and loads it.
}
\author{
Todor Kondić
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mix.R
\name{gen_ftable}
\alias{gen_ftable}
\title{Generate and Load the RMassBank Settings File}
\usage{
gen_ftable(fn_data, wd, n_cmpd)
}
\arguments{
\item{fn_data}{The mzML filename.}
\item{wd}{Directory under which results are archived.}
\item{n_cmpd}{Number of compounds.}
}
\value{
File path of the file table.
}
\description{
Generates file table.
}
\author{
Todor Kondić
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mix.R
\name{gen_stgs_and_load}
\alias{gen_stgs_and_load}
\title{Generate and Load the RMassBank Settings File}
\usage{
gen_stgs_and_load(stgs, wd)
}
\arguments{
\item{stgs}{Settings named list, or a settings filename.}
\item{wd}{Directory under which results are archived.}
}
\value{
result of RMassBank::loadRmbSettings
}
\description{
Generates settings file and loads it.
}
\author{
Todor Kondić
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mix.R
\name{mk_combine_file}
\alias{mk_combine_file}
\title{Combine RMB Settings With Different Collisional Energies}
\usage{
mk_combine_file(sett_fns, fname)
}
\arguments{
\item{sett_fns}{A list of settings files.}
\item{fname}{The name of the combined file.}
}
\value{
fname
}
\description{
Combine the RMB settings files
}
\details{
Combine RMB settings with different collisional energies into one
settings file with multiple collisional energy entries.
}
\author{
Todor Kondić
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mix.R
\name{mk_sett_file}
\alias{mk_sett_file}
\title{Generate RMassBank settings file.}
\usage{
mk_sett_file(sett_alist, file)
}
\arguments{
\item{sett_alist}{The named list of settings that are different
from the RMassBank defaults.}
\item{file}{The name of the YAML specification that will be merged
with the template Rmb settings file.}
}
\description{
Produce the Rmb Settings file
}
\details{
Produce the Rmb Settings file based on the customisation file in
YAML format.
}
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mix.R
\name{no_drama_mkdir}
\alias{no_drama_mkdir}
\title{Create directories without drama}
\usage{
no_drama_mkdir(path)
}
\arguments{
\item{path}{Names of the directories.}
}
\value{
The character string containing the input argument \code{path}.
}
\description{
Create directories without drama.
}
\details{
Create directories without drama.
}
\author{
Todor Kondić
}