library(shiny)
library(mzR)
library(ggplot2)
library(gridExtra)
appwd <- dirname(getwd()) # Get the parent directory of the app
applibpath <- file.path(appwd, "packageLibrary") # Get the path for the "packageLibrary" folder
pwizFolderLocation <- installed.packages(applibpath) # List packages
pwizFolderLocation <- as.list(pwizFolderLocation[grep("proteowizardinstallation",pwizFolderLocation), ]) # find pwiz parent path
pwizFolderLocation <- file.path(pwizFolderLocation$LibPath,"proteowizardinstallation","pwiz") # create pwiz path
remove(appwd, applibpath)
plots <- new.env()
# Define UI for application that draws a histogram
ui <- fluidPage(
# Application title
titlePanel("GNPS Data Conversion and Spectra Quality Check"),
# Sidebar with a slider input for number of bins
sidebarLayout(
sidebarPanel(
actionButton("rawFolderInput", label = "Click to select folder where raw files are"),
fluidRow(column(12, verbatimTextOutput("selectedFolderFileNames", placeholder = TRUE))),
actionButton("outputDirectory", label = "Click to select where mzXML files should be created"),
fluidRow(column(12, verbatimTextOutput("selectedOutputDirectory", placeholder = TRUE))),
actionButton("convertFiles", label = "Click to Convert Files"),
br(),
br(),
uiOutput("uib"),
radioButtons("downloadType", choices = c(".eps", ".ps", ".tex", ".pdf", ".jpeg", ".tiff", ".png", ".bmp", ".svg", ".wmf"),inline=TRUE,label = "Image Type"),
downloadButton("downloadImage", label = "Download Images"),
h3("Warnings"),
br(),
uiOutput("noms2")
),
# Show a plot of the generated distribution
mainPanel(
uiOutput("ms2Plots")
)
)
)
# Define server logic required to draw a histogram
server <- function(input, output, session) {
#---------------------------------------------------------- Select directories
# Selecting folder that contains raw data
rawDataFolder <- reactive({
if(is.null(input$rawFolderInput)){ }else if (input$rawFolderInput > 0){
choose.dir(default = "", caption = "Select files")
}
})
# Selecting folder that contains mzXML files (already-created or to-be-created)
selectedDirectory <- reactive({
if(is.null(input$outputDirectory)){ }else if (input$outputDirectory > 0){
choose.dir()
}
})
#---------------------------------------------------------- Display chosen directories
# List files within the chosen raw-file directory
rawData <- reactive ({
if(is.null(rawDataFolder())){"No Folder Selected"}else{
list.files(rawDataFolder(), recursive = FALSE)}
})
# Render text to display choices chosen
output$selectedFolderFileNames <- renderText({
if(is.null(rawDataFolder())){"No Folder Selected"}else{
paste0(rawData(), "\n")} # Creates user feedback about which raw data folders were chosen. Individual folders displayed on a new line "\n"
})
# Display chosen directory that (will) contain mzXML files
output$selectedOutputDirectory <- renderText({
if(is.null(selectedDirectory())){"No Folder Selected"}else{selectedDirectory()}})
# Display radio selectors for selecting which mzXML file to display
output$uib <- renderUI({
if(is.null(selectedDirectory())){ }else{
mzXMLFiles <- list.files(selectedDirectory(), pattern=".mzXML")
mzXMLFiles2 <- list.files(selectedDirectory(), pattern=".mzXML", full.names = TRUE)
radioButtons("radio", choices = mzXMLFiles2,label = "Converted Files:" )}
})
#---------------------------------------------------------- File Conversion
# Convert raw to mzXML
observeEvent(input$convertFiles, {
rawFiles <- list.files(rawDataFolder(), recursive = FALSE, full.names = TRUE)
fileNames <- sapply(rawFiles, function(x) strsplit(x, "\\.")[[1]][[1]])
zz <- lapply(seq_along(fileNames), function(x){
paste0(file.path(pwizFolderLocation, "msconvert.exe"), " ",
paste0(rawFiles[[x]], collapse = "", sep=" "),
"--filter \"peakPicking true 1-\"",
" --mzXML --32 ",
" -o ",
selectedDirectory(),
" --outfile ",
paste0(fileNames[[x]],".mzXML", " --ignoreUnknownInstrumentError")
)
})
lengthProgress <- length(zz)
withProgress(message = 'Conversion in progress',
detail = 'This may take a while...', value = 0, {
for(i in zz){
incProgress(1/lengthProgress)
system(command = as.character(i))
}
})
})
#---------------------------------------------------------- Read mzXML
readmzXML <- reactive({
req(input$radio)
mzXMLFiles <- list.files(selectedDirectory(), pattern=".mzXML")
mzR::openMSfile(file = input$radio)
})
#----------------------------------------------------------
ticMS1 <- reactive({
list(TIC=mzXMLHeader()$totIonCurrent[mzXMLHeader()$msLevel==1])
})
mzXMLHeader <- reactive({
mzR::header(readmzXML())
})
observeEvent(input$radio,{
output$noms2 <- renderUI("")
if(!any(mzXMLHeader()$msLevel == 1)){ # If no MS1 scans present display warning...
output$noms2 <- renderUI(paste(bquote(NO ~ MS[1] ~ datafound)))
}
if(!any(mzXMLHeader()$msLevel == 2)){ # If no MS2 scans present display warning...
output$noms2 <- renderUI(HTML(paste0("No MS", tags$sup(2)," data found.")))
}
})
observeEvent(input$radio, {
if(!any(mzXMLHeader()$msLevel == 2) & !any(mzXMLHeader()$msLevel == 1)){
}else if(!any(mzXMLHeader()$msLevel == 2)){
output$ms2Plots <- renderUI({
column(12,
plotOutput("distPlot0")
)})
}else if(!any(mzXMLHeader()$msLevel == 1)){
output$ms2Plots <- renderUI({
column(12,
plotOutput("plot1"),
plotOutput("plot2"),
plotOutput("plot3")
)})
}else{
output$ms2Plots <- renderUI({
column(12,
plotOutput("distPlot0"),
plotOutput("plot1"),
plotOutput("plot2"),
plotOutput("plot3"),
plotOutput("plot4")
)})
}
})
#------------------------- Plots
# Plot MS1 Trace
output$distPlot0 <- renderPlot({
relInt <- max(mzXMLHeader()[mzXMLHeader()$msLevel == 1, ]$totIonCurrent) / max(mzXMLHeader()[mzXMLHeader()$msLevel == 1, ]$basePeakIntensity)
plots$p0 <- ggplot(mzXMLHeader()[mzXMLHeader()$msLevel == 1, ]) +
geom_line(aes(x = retentionTime / 60, y = totIonCurrent, colour = "TIC"))+
geom_line(aes(x = retentionTime / 60, y = -basePeakIntensity * (max(totIonCurrent) / max(basePeakIntensity)), colour = "BPC"))+
scale_y_continuous(sec.axis = sec_axis(~. * -(relInt), name = "BPC (As Negative Chromatogram)"))+
scale_colour_manual(values = c("#1b9e77", "#7570b3"))+
theme(legend.position = c(0.8, 0.9))+
labs(y = "TIC", x = "Retention Time (min)", colour = "")+
guides(colour = guide_legend(override.aes = list(size = rel(3)), reverse = T))
plots$p0
})
output$plot1 <- renderPlot({
plots$p1 <- ggplot(mzXMLHeader()[mzXMLHeader()$msLevel==2,]) +
geom_point(aes(x = retentionTime/60, y = precursorMZ, alpha=basePeakIntensity)) +
scale_alpha_continuous(range = c(0.1, 1), trans="log10")+
xlab("Retention Time (min)") +
ylab(bquote(Precursor ~ italic(m/z))) +
labs(alpha= bquote(MS^2 ~ Base ~ Peak ~ Intensity))
plots$p1
})
output$plot2 <- renderPlot({
plots$p2 <- ggplot(mzXMLHeader()[mzXMLHeader()$msLevel==2,]) +
geom_point(aes(x = retentionTime/60, y = peaksCount, alpha=basePeakIntensity, size=precursorMZ)) +
scale_alpha(range = c(0.1, 1), trans="log10")+
scale_size_continuous(range = c(.5, 3.5)) +
xlab("Retention Time (min)") +
ylab(bquote(Number ~ of ~ Peaks ~ "in" ~ MS^2 ~ Scan)) +
labs(alpha= bquote(MS^2 ~ Base ~ Peak ~ Intensity), size= bquote(Precursor ~italic(m/z)))
plots$p2
})
output$plot3 <- renderPlot({
plots$p3 <- ggplot(mzXMLHeader()[mzXMLHeader()$msLevel==2,]) +
geom_point(aes(x = precursorMZ, y = peaksCount, alpha=basePeakIntensity)) +
scale_alpha(range = c(0.1, 1), trans="log10")+
xlab(bquote(Precursor ~ italic(m/z))) +
ylab(bquote(Number ~ of ~ Peaks ~ "in" ~ MS^2 ~ Scan)) +
labs(alpha= bquote(MS^2 ~ Base ~ Peak ~ Intensity))
plots$p3
})
output$downloadImage <- downloadHandler(
filename = function(){paste0("Output", input$downloadType)},
content = function(file1){
q0<-plots$p0 +labs(tag="A")
q1<-plots$p1 +labs(tag="B")
q2<-plots$p2 +labs(tag="C")
q3<-plots$p3 +labs(tag="D")
captionTitle <- 'bold("Caption:")'
captionA <- 'bold("A:")~" Description of plot A"'
captionB <- 'bold("B:")~" Description of plot A"'
captionC <- 'bold("C:")~" Description of plot A"'
captionD <- 'bold("D:")~" Description of plot A"'
q4 <- ggplot() +
annotate("text", x = 2.5, y = 26, size=8, label = captionTitle, parse = TRUE) +
annotate("text", x = 4, y = 25, size=8, label = captionA, parse = TRUE) +
annotate("text", x = 4, y = 24, size=8, label = captionB, parse = TRUE) +
annotate("text", x = 4, y = 23, size=8, label = captionC, parse = TRUE) +
annotate("text", x = 4, y = 22, size=8, label = captionD, parse = TRUE) +
theme_void()+
coord_cartesian(xlim=c(2,6), ylim=c(20,30))
l1 <- gridExtra::grid.arrange(q0)
l2 <- gridExtra::grid.arrange(q1, q2, nrow = 1)
l3 <- gridExtra::grid.arrange(q3, nrow = 1)
ww <- gridExtra::grid.arrange(l1,l2,l3, nrow=3, heights=c(.9,.9,.9))
ggplot2::ggsave(file1, plot=ww, width= 38, height= 28, units= "cm")
if (file.exists(paste0(file1, input$downloadType)))
file.rename(paste0(file1, input$downloadType), file1)
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.