Commit 7f7ba4a5 authored by svolant's avatar svolant
Browse files

modif masque integration

parent 8e65da7d
options(download.file.method = 'wget') options(download.file.method = 'wget')
if (!require("backports")){
install.packages("backports") if (!require("sendmailR")){
library(backports) install.packages("sendmailR")
library(sendmailR)
}
if (!require("shinyBS")){
install.packages("shinyBS")
library(shinyBS)
}
library(tools)
if (!require("flexdashboard")){
install.packages("flexdashboard")
library(flexdashboard)
} }
if (!require("backports")){ if (!require("backports")){
install.packages("backports") install.packages("backports")
library(backports)
} }
if (!require("readr")){ if (!require("readr")){
install.packages("readr") install.packages("readr")
library(readr) library(readr)
......
...@@ -236,16 +236,32 @@ CheckMasque <- function(input,values) ...@@ -236,16 +236,32 @@ CheckMasque <- function(input,values)
Error = NULL Error = NULL
HowTo = NULL HowTo = NULL
## Check password
if(is.null(Error) && input$password == ""){
Error = "<h6><strong>Empty key field </strong></h6>"
HowTo = "<h6><strong>Make sure that you have click the &laquo Get key &raquo button and that you have pasted the key sent by mail </strong></h6>"
}
if(is.null(Error) && input$password != ""){
pass = toupper(gsub(" ","",input$password))
if(!identical(pass,toupper(values$pass))){
Error = "<h6><strong>Invalid key </strong></h6>";
HowTo = "<h6><strong>Make sure that you have click the &laquo Get key &raquo button and that you have pasted the key sent by mail</strong></h6>"
}
}
## At least one fastq is detected ## At least one fastq is detected
if(is.null(Error) && input$LoadFiles>0 && length(values$fastq_names_only)==0){ if(is.null(Error) && input$LoadFiles>0 && length(values$fastq_names_only)==0){
Error = "The selected directory must contain at least one file in the following format : fastq, fastq.gz, or fq." Error = "<h6><strong>The selected directory must contain at least one file in the following format : fastq, fastq.gz, or fq.</strong></h6>"
HowTo = "Change the working directory and check the format of the files" HowTo = "<h6><strong>Change the working directory and check the format of the files</strong></h6>"
} }
if(is.null(Error) && input$PairedOrNot=='y' && input$MatchFiles_button>0){ if(is.null(Error) && input$PairedOrNot=='y' && input$MatchFiles_button>0){
if(length(values$R2fastQ) !=length(values$R2fastQ)){ if(length(values$R2fastQ) !=length(values$R2fastQ)){
Error = "The number of fastq files for R1 and R2 must be the same" Error = "<h6><strong>The number of fastq files for R1 and R2 must be the same</strong></h6>"
HowTo = "Add/Remove some files or change the suffix to identify the pairs" HowTo = "<h6><strong>Add/Remove some files or change the suffix to identify the pairs</strong></h6>"
} }
if(length(values$R2fastQ)>0 && length(values$R2fastQ)>0){ if(length(values$R2fastQ)>0 && length(values$R2fastQ)>0){
...@@ -254,27 +270,30 @@ CheckMasque <- function(input,values) ...@@ -254,27 +270,30 @@ CheckMasque <- function(input,values)
dup_files = c(values$R1fastQ[duplicated(tmpR1)],values$R2fastQ[duplicated(tmpR2)]) dup_files = c(values$R1fastQ[duplicated(tmpR1)],values$R2fastQ[duplicated(tmpR2)])
if(length(dup_files)>0){ if(length(dup_files)>0){
Error = paste("These fastq files corresponds to the same sample names:" ,dup_files) Error = paste("<h6><strong>These fastq files corresponds to the same sample names:</strong></h6>" ,dup_files)
HowTo = "Change the suffix to identify the pairs" HowTo = "<h6><strong>Change the suffix to identify the pairs</strong></h6>"
} }
if(!isValidPrimer(input$R1primer)){ Error = "The primer (forward) must only contain letters from A to Z" } if(!isValidPrimer(input$R1primer)){ Error = "<h6><strong>The primer (forward) must only contain letters from A to Z</strong></h6>" }
if(!isValidPrimer(input$R2primer)){ Error = "The primer (reverse) must only contain letters from A to Z" } if(!isValidPrimer(input$R2primer)){ Error = "<h6><strong>The primer (reverse) must only contain letters from A to Z</strong></h6>" }
} }
} }
if(is.null(Error) && !isValidEmail(input$to)) Error = "The email address is not valid" if(is.null(Error) && !isValidEmail(input$to)) Error = "<h6><strong>The email address is not valid</strong></h6>"
if(is.null(Error) && !isValidPrimer(input$primerSingle)){ Error = "The primer must only contain letters from A to Z" }
if(is.null(Error) && !isValidPrimer(input$primerSingle)){ Error = "<h6><strong>The primer must only contain letters from A to Z</strong></h6>" }
if(is.null(Error)) { if(is.null(Error)) {
res = SamplesMasque(input,values) res = SamplesMasque(input,values)
if(length(res$samples)==0) { if(length(res$samples)==0) {
Error = "0 sample detected" Error = "<h6><strong>0 sample detected</strong></h6>"
if(input$PairedOrNot=='y') HowTo = "Change the working directory and/or verify the pairs matching" if(input$PairedOrNot=='y') HowTo = '<h6><strong>Make sur that you click the &laquo Load &raquo button. <br /> Change the working directory and/or verify the pairs matching.</strong></h6>'
if(input$PairedOrNot=='n') HowTo = "Change the working directory and load fastq files" if(input$PairedOrNot=='n') HowTo = '<h6><strong>Make sur that you click the &laquo Load &raquo button. <br /> Change the working directory.</strong></h6>'
} }
} }
...@@ -316,9 +335,8 @@ SamplesMasque <- function(input,values) ...@@ -316,9 +335,8 @@ SamplesMasque <- function(input,values)
CreateJSON <- function(input){ CreateJSON <- function(input,values){
curdir <- getwd()
tmpjson = tempfile(pattern = "file", tmpdir = paste(curdir,"www","masque","todo",sep= .Platform$file.sep), fileext = ".json")
if(input$PairedOrNot=='n') if(input$PairedOrNot=='n')
{ {
...@@ -327,11 +345,11 @@ CreateJSON <- function(input){ ...@@ -327,11 +345,11 @@ CreateJSON <- function(input){
"path"=path_fastq, "path"=path_fastq,
"host"=input$HostName, "host"=input$HostName,
"type"=input$DataTypeMasque, "type"=input$DataTypeMasque,
"mail"=input$to, "mail"=values$login_email,
"contaminant"= "/home/aghozlan/workspace/shaman_bioblend/alienTrimmerPF8contaminants.fasta" "contaminant"= "/home/aghozlan/workspace/shaman_bioblend/alienTrimmerPF8contaminants.fasta"
) )
df %>% jsonlite::toJSON() %>% write_lines(tmpjson) df %>% jsonlite::toJSON() %>% write_lines(values$json_name)
} }
if(input$PairedOrNot=='y') if(input$PairedOrNot=='y')
{ {
...@@ -343,10 +361,10 @@ CreateJSON <- function(input){ ...@@ -343,10 +361,10 @@ CreateJSON <- function(input){
"path_R2"=path_fastq_R2, "path_R2"=path_fastq_R2,
"host"=input$HostName, "host"=input$HostName,
"type"=input$DataTypeMasque, "type"=input$DataTypeMasque,
"mail"=input$to, "mail"=values$login_email,
"contaminant"= "/home/aghozlan/workspace/shaman_bioblend/alienTrimmerPF8contaminants.fasta" "contaminant"= "/home/aghozlan/workspace/shaman_bioblend/alienTrimmerPF8contaminants.fasta"
) )
df %>% jsonlite::toJSON() %>% write_lines(tmpjson) df %>% jsonlite::toJSON() %>% write_lines(values$json_name)
} }
} }
......
...@@ -50,3 +50,12 @@ text-align: center; ...@@ -50,3 +50,12 @@ text-align: center;
color: #FFFFFF; color: #FFFFFF;
} }
" "
gaugeCSS <- "
.html-widget.gauge svg {
height: 100%;
margin-top: -10px;
margin-bottom: -40px;
}
"
...@@ -21,11 +21,16 @@ shinyServer(function(input, output,session) { ...@@ -21,11 +21,16 @@ shinyServer(function(input, output,session) {
curdir = getwd() curdir = getwd()
json_name = tempfile(pattern = "file", tmpdir = paste(curdir,"www","masque","todo",sep= .Platform$file.sep), fileext = ".json") json_name = tempfile(pattern = "file", tmpdir = paste(curdir,"www","masque","todo",sep= .Platform$file.sep), fileext = ".json")
## Pass for MASQUE
pass = gsub("file","",basename(file_path_sans_ext(json_name)))
## Popup messages ## Popup messages
observe(if(input$AddRegScatter) info("By adding the regression line, you will lose interactivity.")) observe(if(input$AddRegScatter) info("By adding the regression line, you will lose interactivity."))
## Reactive target ## Reactive target
values <- reactiveValues(TargetWorking = target,labeled=NULL,fastq_names_only=NULL,R1fastQ=NULL,R2fastQ=NULL,json_name=json_name) values <- reactiveValues(TargetWorking = target,labeled=NULL,fastq_names_only=NULL,R1fastQ=NULL,R2fastQ=NULL,
json_name=json_name,num=0,pass=pass,login_email = NULL,is.valid =NULL,
biom_masque = NULL,tree_masque=NULL)
## Counts file ## Counts file
dataInputCounts <-reactive({ dataInputCounts <-reactive({
...@@ -92,13 +97,19 @@ shinyServer(function(input, output,session) { ...@@ -92,13 +97,19 @@ shinyServer(function(input, output,session) {
data = NULL data = NULL
inFile <- input$fileBiom inFile <- input$fileBiom
if (is.null(inFile)) return(NULL) if (!is.null(inFile) && is.null(values$biom_masque)) {
try(read_biom(inFile$datapath)->data,silent=T) try(read_biom(inFile$datapath)->data,silent=T)
}
if (!is.null(values$biom_masque) && file.exists(values$biom_masque)) try(read_biom(values$biom_masque)->data,silent=T)
return(data) return(data)
}) })
observeEvent(input$fileBiom,{
values$biom_masque=NULL;
})
## Unifrac File (tree) ## Unifrac File (tree)
...@@ -107,12 +118,27 @@ shinyServer(function(input, output,session) { ...@@ -107,12 +118,27 @@ shinyServer(function(input, output,session) {
data = NULL data = NULL
inFile <- input$fileTree inFile <- input$fileTree
if (is.null(inFile)) return(NULL) if (!is.null(inFile) && is.null(values$tree_masque)) {
try(read.tree(inFile$datapath)->data, silent=T) try(read.tree(inFile$datapath)->data, silent=T)
CheckTree = CheckTreeFile(data) CheckTree = CheckTreeFile(data)
data = CheckTree$tree data = CheckTree$tree
try(readLines(inFile$datapath)->treeseq, silent=T) try(readLines(inFile$datapath)->treeseq, silent=T)
return(list(data=data, Error=CheckTree$Error, Warning=CheckTree$Warning, treeseq=treeseq)) return(list(data=data, Error=CheckTree$Error, Warning=CheckTree$Warning, treeseq=treeseq))
}
if (!is.null(values$tree_masque) && file.exists(values$tree_masque)) {
try(read.tree(values$tree_masque)->data, silent=T)
CheckTree = CheckTreeFile(data)
data = CheckTree$tree
try(readLines(values$tree_masque)->treeseq, silent=T)
return(list(data=data, Error=CheckTree$Error, Warning=CheckTree$Warning, treeseq=treeseq))
}
})
observeEvent(input$fileTree,{
values$tree_masque=NULL;
}) })
...@@ -672,6 +698,7 @@ shinyServer(function(input, output,session) { ...@@ -672,6 +698,7 @@ shinyServer(function(input, output,session) {
observeEvent(input$submit,{ observeEvent(input$submit,{
CMP = CheckMasque(input, values) CMP = CheckMasque(input, values)
Error = CMP$Error Error = CMP$Error
values$num = 0
if(is.null(Error)) if(is.null(Error))
{ {
...@@ -712,10 +739,12 @@ shinyServer(function(input, output,session) { ...@@ -712,10 +739,12 @@ shinyServer(function(input, output,session) {
} }
## Create JSON file ## Create JSON file
withProgress(message = 'Creating JSON file...',{CreateJSON(input,values$json_name)}) withProgress(message = 'Creating JSON file...',{CreateJSON(input,values)})
if(file.exists(values$json_name)) values$num = 1
info("Your data have been submitted. You will receive an e-mail once the computation over.\nThis can take few hours")
} }
}) },priority = 1)
...@@ -862,7 +891,7 @@ shinyServer(function(input, output,session) { ...@@ -862,7 +891,7 @@ shinyServer(function(input, output,session) {
if(!is.null(CMP$Error) && input$submit>0) { if(!is.null(CMP$Error) && input$submit>0) {
box(title = "Error", status = "danger",width = 12, box(title = "Error", status = "danger",width = 12,
h6(strong(CMP$Error)) HTML(CMP$Error)
) )
} else return(NULL) } else return(NULL)
...@@ -875,26 +904,196 @@ shinyServer(function(input, output,session) { ...@@ -875,26 +904,196 @@ shinyServer(function(input, output,session) {
if(!is.null(CMP$HowTo) && input$submit>0) { if(!is.null(CMP$HowTo) && input$submit>0) {
box(title = "How To", status = "success",width = 12, box(title = "How To", status = "success",width = 12,
h6(strong(CMP$HowTo)) HTML(CMP$HowTo)
) )
} else return(NULL) } else return(NULL)
}) })
## plot gauge
output$gaugeMasque <-renderGauge({
input$submit
res = NULL;
num = as.numeric(values$num)
CMP = isolate(CheckMasque(input, values))
Error = CMP$Error
if(is.null(Error) || num!=0) res = gauge(min(num,100), 0,100,symbol = '%',label= "Progress...")
return(res)
})
output$gaugeMasque <-renderGauge({ ## Timer for the gauge
Timer <- reactiveTimer(5000)
## Check masque progress
observe({
Timer()
# values$num = isolate(values$num)*5
progress_file = paste(curdir,"www","masque","doing",paste(basename(file_path_sans_ext(json_name)),".txt",sep=""),sep= .Platform$file.sep)
if(file.exists(progress_file))
{
pf = read_lines(progress_file)
pf = as.numeric(pf)
if(!is.na(pf)){
pf = min(pf,100); pf = max(pf,0)
if(isolate(values$num)<pf) {values$num = pf}
}
}
})
observe({
toggleState("checkMail",condition = isValidEmail(input$to))
})
output$pass_Arg <- renderUI({
pass = toupper(gsub(" ","",input$password))
passOK = identical(pass,toupper(values$pass))
values$json_name if(!is.null(input$password) && input$password!="" && !passOK){
num = 0 removeCssClass(class = 'pwdGREEN', selector = '#password')
gauge(num, 0,100,symbol = '%') addCssClass(class = 'pwdRED', selector = '#password')
}
if(!is.null(input$password) && input$password!="" && passOK){
removeCssClass(class = 'pwdRED', selector = '#password')
addCssClass(class = 'pwdGREEN', selector = '#password')
}
if(is.null(input$password) || input$password==""){
removeCssClass(class = 'pwdRED', selector = '#password')
removeCssClass(class = 'pwdGREEN', selector = '#password')
}
}) })
textMASQUE <- reactive({
samp = SamplesMasque(input,values)
home <- normalizePath("~")
path_glob = file.path(home, paste(unlist(dir()$path[-1]), collapse = .Platform$file.sep))
text = paste("<b>Type of data:</b>",input$DataTypeMasque,"<br /> <br /> ",
"<b>Paired-end sequencing:</b>",input$PairedOrNot)
text = paste(text,"<br /> <br /> ","<b>Number of samples:</b>",length(samp$samples))
text = paste(text,"<br /> <br /> ","<b>Removed samples:</b>",length(samp$samples_removed))
text = paste(text,"<br /> <br /> ","<b>Working directory:</b>",path_glob)
if(isValidEmail(input$to)) text = paste(text,"<br /> <br /> ","<b>Email:</b>",input$to)
if(input$HostName!="") text = paste(text,"<br /> <br /> ","<b>Host:</b>",input$HostName)
if(input$primer && input$PairedOrNot=="n") {text = paste(text,"<br /> <br /> ","<b>Primer:</b>",input$primerSingle)}
if(input$primer && input$PairedOrNot=="y") {text = paste(text,"<br /> <br /> ","<b>Primer forward:</b>",input$R1primer,
"<br /> <br /> ","<b>Primer reverse:</b>",input$R2primer)}
return(text)
})
output$summary_box_masque <- renderUI({
text = textMASQUE()
res = div(style = "word-wrap: break-word;",box(
title = strong("Summary of your analysis"), width = 12, background = "light-blue",
HTML(text),
div(style = "text-align:right;",
downloadButton("printMasque_summary", "Save"),
tags$style(type='text/css', "#printMasque_summary {margin-top: 15px;}")
)
)
)
return(res)
})
## Export MASQUE summary in .txt
output$printMasque_summary <- downloadHandler(
filename = function() { 'Summary.txt' },
content = function(file){
txt = textMASQUE()
txt = gsub("<br />",replacement = "\n",txt)
txt = gsub("</b>",replacement = "",txt)
txt = gsub("<b>",replacement = "",txt)
write(paste("Summary of your analysis \n \n ",txt), file)
}
)
## Send mail with the password
observeEvent(input$checkMail,{
observe( info(paste("You will received a password by email at :",isolate(input$to), '\nThis can take few seconds.')))
to <- isolate(input$to)
subject <- "SHAMAN Analysis"
body <- paste("Hello, \n You are using SHAMAN to run a quantitative metagenomic analysis. Hereafter is the key you need in SHAMAN :
\n",values$pass," \n \n Best regards, \n SHAMAN team")
mailControl=list(smtpServer="smtp.pasteur.fr")
from="<shaman@pasteur.fr>"
## Send mail
sendmail(from=from,to=to,subject=subject,msg=body,control=mailControl)
## Store the email
values$login_email = to
})
## Create button once MASQUE computation is over
output$MasqueToShaman_button <- renderUI({
input$submit
res = NULL
CMP = isolate(CheckMasque(input, values))
Error = CMP$Error
if(is.null(Error) && values$num<1){
res = box(id="load-masque-res",title="Upload the results",width = 12, status = "success",
selectInput("masque_database","Select the database",choices=c("Silva" = "silva","Greengenes" = "greengenes")),
tags$style(type='text/css', "#masque-database { width:100%; margin-top: 5px;}"),
actionButton("RunResMasque",label = "Upload the results",icon=icon('upload')),
tags$style(type='text/css', "#RunResMasque { width:100%; margin-top: 15px;}")
)
}
return(res)
})
observe({
if(values$num<100) disable("RunResMasque")
if(values$num<100) disable("masque_database")
if(values$num<100){ addPopover(session,"load-masque-res",
title= "Waiting for the results",
content = paste("Once the computation is over, you will received a password by email at:",values$login_email)
)
} else removePopover(session, "load-masque-res")
})
observeEvent(input$RunResMasque,{
updateSelectInput(session, "FileFormat","",selected = "fileBiom")
reset("fileBiom"); reset("fileTree")
values$biom_masque = paste(curdir,"www","masque","done",basename(file_path_sans_ext(json_name)),paste("shaman_",input$masque_database,".biom",sep=""),sep= .Platform$file.sep)
values$tree_masque = paste(curdir,"www","masque","done",basename(file_path_sans_ext(json_name)),paste("shaman_tree_",input$masque_database,".nhx",sep=""),sep= .Platform$file.sep)
})
######################## END MASQUE ################################# ######################## END MASQUE #################################
observeEvent(input$deleteRows,{ observeEvent(input$deleteRows,{
if (!is.null(input$DataTarget_rows_selected)) { if (!is.null(input$DataTarget_rows_selected)) {
...@@ -1670,7 +1869,7 @@ shinyServer(function(input, output,session) { ...@@ -1670,7 +1869,7 @@ shinyServer(function(input, output,session) {
tmpBIOM = dataInputBiom() tmpBIOM = dataInputBiom()
if(!is.null(inFile) && is.null(tmpBIOM)) { if(!is.null(inFile) && is.null(tmpBIOM)) {
box(title = "Error", status = "danger",width = 3, box(title = "Error", status = "danger",width = 12,
h5(strong("This file can not be loaded.")),br(), h5(strong("This file can not be loaded.")),br(),
em("The loaded file is not in the biom format or its format is not currently supported by SHAMAN software") em("The loaded file is not in the biom format or its format is not currently supported by SHAMAN software")
) )
...@@ -1687,7 +1886,7 @@ shinyServer(function(input, output,session) { ...@@ -1687,7 +1886,7 @@ shinyServer(function(input, output,session) {
Counts = dataInputCounts() Counts = dataInputCounts()
if(!is.null(inFile) && is.null(Counts)) { if(!is.null(inFile) && is.null(Counts)) {
box(title = "Error", status = "danger",width = 3, box(title = "Error", status = "danger",width = 12,
h5(strong("This file can not be loaded.")),br(), h5(strong("This file can not be loaded.")),br(),
em("The count table file is not in the correct format for SHAMAN software") em("The count table file is not in the correct format for SHAMAN software")
) )
...@@ -1704,7 +1903,7 @@ shinyServer(function(input, output,session) { ...@@ -1704,7 +1903,7 @@ shinyServer(function(input, output,session) {
Taxo = dataInputTaxo() Taxo = dataInputTaxo()
if(!is.null(inFile) && !input$NoTaxoFile && is.null(Taxo)) {