Commit 9b70ee7c authored by svolant's avatar svolant
Browse files

ajout masque

parent 1bf5e36e
options(download.file.method = 'wget')
if (!require("readr")){
install.packages("readr")
}
if (!require("jsonlite")){
install.packages("jsonlite")
}
if (!require("shinyFiles")){
install.packages("shinyFiles")
}
if (!require("Rcpp")){
install.packages("Rcpp")
}
......
......@@ -229,6 +229,129 @@ CheckTreeFile <- function(tree)
}
## Check Masque Input
CheckMasque <- function(input,values)
{
Error = NULL
HowTo = NULL
## At least one fastq is detected
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."
HowTo = "Change the working directory and check the format of the files"
}
if(is.null(Error) && input$PairedOrNot=='y' && input$MatchFiles_button>0){
if(length(values$R2fastQ) !=length(values$R2fastQ)){
Error = "The number of fastq files for R1 and R2 must be the same"
HowTo = "Add/Remove some files or change the suffix to identify the pairs"
}
if(length(values$R2fastQ)>0 && length(values$R2fastQ)>0){
tmpR1 = gsub(input$R1files,x=values$R1fastQ,"")
tmpR2 = gsub(input$R2files,x=values$R2fastQ,"")
dup_files = c(values$R1fastQ[duplicated(tmpR1)],values$R2fastQ[duplicated(tmpR2)])
if(length(dup_files)>0){
Error = paste("These fastq files corresponds to the same sample names:" ,dup_files)
HowTo = "Change the suffix to identify the pairs"
}
if(!isValidPrimer(input$R1primer)){ Error = "The primer (forward) must only contain letters from A to Z" }
if(!isValidPrimer(input$R2primer)){ Error = "The primer (reverse) must only contain letters from A to Z" }
}
}
if(is.null(Error) && !isValidEmail(input$to)) Error = "The email address is not valid"
if(is.null(Error) && !isValidPrimer(input$primerSingle)){ Error = "The primer must only contain letters from A to Z" }
if(is.null(Error)) {
res = SamplesMasque(input,values)
if(length(res$samples)==0) {
Error = "0 sample detected"
if(input$PairedOrNot=='y') HowTo = "Change the working directory and/or verify the pairs matching"
if(input$PairedOrNot=='n') HowTo = "Change the working directory and load fastq files"
}
}
return(list(Error=Error,HowTo=HowTo))
}
isValidEmail <- function(x) {
grepl("\\<[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\>", as.character(x), ignore.case=TRUE)
}
isValidPrimer <- function(x) {
!any(!grepl("[A-Z]",unlist(strsplit(x,""))))
}
SamplesMasque <- function(input,values)
{
samples_removed = NULL
samples = NULL
if(input$PairedOrNot=='y')
{
tmpR1 = gsub(input$R1files,x=values$R1fastQ,"")
tmpR2 = gsub(input$R2files,x=values$R2fastQ,"")
R1samples = tmpR1[tmpR1%in%tmpR2]; R1samples_removed = values$R1fastQ[!tmpR1%in%tmpR2]
R2samples = tmpR2[tmpR2%in%tmpR1]; R2samples_removed = values$R2fastQ[!tmpR2%in%tmpR1]
samples = unique(c(R1samples,R2samples))
samples_removed = c(R1samples_removed,R2samples_removed)
} else {samples = unique(values$fastq_names_only)}
return(list(samples=samples,samples_removed=samples_removed))
}
CreateJSON <- function(input){
tmpjson = tempfile(pattern = "file", tmpdir = "/Volumes/@home/Projets Hub/Metagenomique/meta16s/www/masque/todo", fileext = ".json")
file.create(tmpjson,showWarnings=FALSE)
if(input$PairedOrNot=='n')
{
path_fastq = paste(tempdir(),"Masque_files",sep= .Platform$file.sep)
df = data.frame("paired"=FALSE,
"path"=path_fastq,
"host"=input$HostName,
"type"=input$DataTypeMasque,
"mail"=input$to,
"contaminant"= "/home/aghozlan/workspace/shaman_bioblend/alienTrimmerPF8contaminants.fasta"
)
df %>% jsonlite::toJSON() %>% write_lines(tmpjson)
}
if(input$PairedOrNot=='y')
{
path_fastq_R1 = paste(tempdir(),"Masque_files_R1",sep= .Platform$file.sep)
path_fastq_R2 = paste(tempdir(),"Masque_files_R2",sep= .Platform$file.sep)
df = data.frame("paired"=FALSE,
"path_R1"=path_fastq_R1,
"path_R2"=path_fastq_R2,
"host"=input$HostName,
"type"=input$DataTypeMasque,
"mail"=input$to,
"contaminant"= "/home/aghozlan/workspace/shaman_bioblend/alienTrimmerPF8contaminants.fasta"
)
df %>% jsonlite::toJSON() %>% write_lines(tmpjson)
}
}
## Get the percentage of annotated OTU
PercentAnnot <- function(counts,taxo)
{
......
......@@ -20,7 +20,7 @@ shinyServer(function(input, output,session) {
observe(if(input$AddRegScatter) info("By adding the regression line, you will lose interactivity."))
## Reactive target
values <- reactiveValues(TargetWorking = target,labeled=NULL)
values <- reactiveValues(TargetWorking = target,labeled=NULL,fastq_names_only=NULL,R1fastQ=NULL,R2fastQ=NULL)
## Counts file
dataInputCounts <-reactive({
......@@ -605,25 +605,280 @@ shinyServer(function(input, output,session) {
})
# ## Select a folder (for MASQUE)
# observeEvent(
# ignoreNULL = TRUE,
# eventExpr = {
# input$directory
# },
# handlerExpr = {
# # if (input$directory > 0) {
# # condition prevents handler execution on initial app launch
#
# # launch the directory selection dialog with initial path read from the widget
# path = choose.dir(default = readDirectoryInput(session, 'directory'))
#
# # update the widget value
# updateDirectoryInput(session, 'directory', value = path)
# # }
# }
# )
#############################################################
##
## MASQUE
##
#############################################################
## Select a folder (for MASQUE)
observeEvent(
ignoreNULL = TRUE,
eventExpr = {
input$directory
},
handlerExpr = {
if (input$directory > 0) {
# condition prevents handler execution on initial app launch
shinyDirChoose(input, 'dir', roots = c(home = '~'),filetypes = c('', 'fastq','gz','fgz'))
dir <- reactive(input$dir)
output$dirSel <- renderText({
home <- normalizePath("~")
path_glob = file.path(home, paste(unlist(dir()$path[-1]), collapse = .Platform$file.sep))
})
path <- reactive({
home <- normalizePath("~")
# file.path(home, paste(unlist(dir()$path[-1]), collapse = .Platform$file.sep),"*.pdf")
file.path(home, paste(unlist(dir()$path[-1]), collapse = .Platform$file.sep),"*.f*q*")
})
# observeEvent(input$submit,{
# values$fastq_names_only = NULL
# tmp = tempdir()
# pathTo = paste(tmp,"Masque_files",sep=.Platform$file.sep)
#
# if (dir.exists(pathTo))
# {
# file.remove(list.files(pathTo,full.names =TRUE))
# } else dir.create(pathTo)
#
# file.copy(from=Sys.glob(path()), to=paste(tmp,"Masque_files",sep= .Platform$file.sep))
# })
#
observeEvent(input$submit,{
CMP = CheckMasque(input, values)
Error = CMP$Error
if(is.null(Error))
{
tmp = tempdir()
home <- normalizePath("~")
path_glob = file.path(home, paste(unlist(dir()$path[-1]), collapse = .Platform$file.sep))
## Paired-end
if(input$PairedOrNot=="y"){
cmp = 0
nfiles = length(values$R1fastQ)+length(values$R2fastQ)
withProgress(message = 'Uploading files...', value = 0, {
pathToR1 = paste(tmp,"Masque_files_R1",sep=.Platform$file.sep)
pathToR2 = paste(tmp,"Masque_files_R2",sep=.Platform$file.sep)
if(dir.exists(pathToR1)){file.remove(list.files(pathToR1,full.names =TRUE))} else dir.create(pathToR1)
if(dir.exists(pathToR2)){file.remove(list.files(pathToR2,full.names =TRUE))} else dir.create(pathToR2)
for(i in values$R1fastQ){file.copy(from=paste(path_glob,i,sep=.Platform$file.sep), to=paste(tmp,"Masque_files_R1",sep= .Platform$file.sep));cmp = cmp +1;incProgress(cmp/nfiles, detail = "Forward fastq files...")}
for(i in values$R2fastQ){file.copy(from=paste(path_glob,i,sep=.Platform$file.sep), to=paste(tmp,"Masque_files_R2",sep= .Platform$file.sep));cmp = cmp +1;incProgress(cmp/nfiles, detail = "Reverse fastq files...")}
})
# launch the directory selection dialog with initial path read from the widget
path = choose.dir(default = readDirectoryInput(session, 'directory'))
} else{
cmp = 0
nfiles = length(values$fastq_names_only)
withProgress(message = 'Uploading files...', value = 0, {
pathTo = paste(tmp,"Masque_files",sep=.Platform$file.sep)
# update the widget value
updateDirectoryInput(session, 'directory', value = path)
if(dir.exists(pathTo)){file.remove(list.files(pathTo,full.names =TRUE))} else dir.create(pathTo)
for(i in values$fastq_names_only){file.copy(from=paste(path_glob,i,sep=.Platform$file.sep), to=paste(tmp,"Masque_files",sep= .Platform$file.sep));cmp = cmp +1;incProgress(cmp/nfiles)}
})
}
## Create JSON file
withProgress(message = 'Creating JSON file...',{CreateJSON(input)})
}
})
## FastQ list
output$FastQList_out <- renderUI({
input$LoadFiles
NullBox = h3(strong("0 FastQ file detected"),style="color:red; text-align: center")
res = NullBox
home <- normalizePath("~")
path_glob = file.path(home, paste(unlist(isolate(dir()$path[-1])), collapse = .Platform$file.sep))
fastq_names = Sys.glob(isolate(path()))
if(length(fastq_names)>0 && input$LoadFiles>0)
{
if(is.null(values$fastq_names_only) || length(values$fastq_names_only)==0) values$fastq_names_only = gsub(pattern = path_glob,x = fastq_names,replacement = "")
# res = box(title="Select your FastQ files",width = 6, status = "primary",
# selectInput("FastQList",label = "List of the fastq files in the selected directory",values$fastq_names_only,multiple =TRUE,selectize=FALSE,size = 6),
# actionButton("RemoveFastQbut",'Remove file(s)',icon=icon("remove"))
# )
res =list(
selectInput("FastQList",label = "List of the fastq files in the selected directory",values$fastq_names_only,multiple =TRUE,selectize=FALSE,size = 6),
actionButton("RemoveFastQbut",'Remove file(s)',icon=icon("remove"))
)
} else res = NullBox
return(res)
})
observeEvent(input$LoadFiles,{
values$fastq_names_only = NULL
})
## Remove FastQ function
RemoveFastQ <-eventReactive(input$RemoveFastQbut,{
if(length(input$FastQList)>0)
{
ind = which(values$fastq_names_only%in% input$FastQList)
values$fastq_names_only = values$fastq_names_only[-ind]
updateSelectInput(session, "FastQList","List of the fastq files in the selected directory",values$fastq_names_only)
}
})
## Remove FastQ
observeEvent(input$RemoveFastQbut,{
RemoveFastQ()
if(input$MatchFiles_button>=1) MatchFiles()
},priority=1)
## Update R1 and R2 lists
MatchFiles <-reactive({
if(length(values$fastq_names_only)>0 && input$PairedOrNot=='y')
{
indR1 = grep(input$R1files,values$fastq_names_only)
indR2 = grep(input$R2files,values$fastq_names_only)
## If some are R1 and R2, removed from both list
b12 = intersect(indR1,indR2)
if(length(b12)>0) {indR1 = indR1[-which(indR1%in%b12)]; indR2 = indR2[-which(indR2%in%b12)]}
if(length(indR1)>0 && length(indR2)>0){
values$R1fastQ = values$fastq_names_only[indR1]
values$R2fastQ = values$fastq_names_only[indR2]
## If some are only R1 or R2
tmpR1 = gsub(input$R1files,x=values$R1fastQ,""); tmpR2 = gsub(input$R2files,x=values$R2fastQ,"")
values$R1fastQ = values$R1fastQ[tmpR1%in%tmpR2];values$R2fastQ = values$R2fastQ[tmpR2%in%tmpR1]
## Update the files lists
updateSelectInput(session, "R1filesList","",values$R1fastQ); updateSelectInput(session, "R2filesList","",values$R2fastQ)
} else{updateSelectInput(session, "R1filesList","","");updateSelectInput(session, "R2filesList","","")}
} else{updateSelectInput(session, "R1filesList","","");updateSelectInput(session, "R2filesList","","")}
})
observeEvent(input$MatchFiles_button,{
MatchFiles()
},priority=1)
## Remove FastQ function directly from R1, R2
RemoveFastQ_R1R2 <-eventReactive(input$RemoveFastQbut_R1R2,{
if(length(input$R1filesList)>0)
{
ind = which(values$R1fastQ%in% input$R1filesList)
values$R1fastQ = values$R1fastQ[-ind]
updateSelectInput(session, "R1filesList","",values$R1fastQ)
}
if(length(input$R2filesList)>0)
{
ind = which(values$R2fastQ%in% input$R2filesList)
values$R2fastQ = values$R2fastQ[-ind]
updateSelectInput(session, "R2filesList","",values$R2fastQ)
}
})
## Remove FastQ from R1, R2
observeEvent(input$RemoveFastQbut_R1R2,{
RemoveFastQ_R1R2()
},priority=1)
# observe({
# CMP = CheckMasque(input, values)
# toggleState("submit",condition = is.null(CMP$Error))
# })
observe({
toggleState("box-match",condition = (input$PairedOrNot=="y"))
})
output$InfoMasque<- renderUI({
input$submit
CMP = isolate(CheckMasque(input, values))
if(!is.null(CMP$Error) && input$submit>0) {
box(title = "Error", status = "danger",width = 12,
h6(strong(CMP$Error))
)
} else return(NULL)
})
output$InfoMasqueHowTo<- renderUI({
input$submit
CMP = isolate(CheckMasque(input, values))
if(!is.null(CMP$HowTo) && input$submit>0) {
box(title = "How To", status = "success",width = 12,
h6(strong(CMP$HowTo))
)
} else return(NULL)
})
######################## END MASQUE #################################
observeEvent(input$deleteRows,{
if (!is.null(input$DataTarget_rows_selected)) {
......
......@@ -259,11 +259,77 @@ body <- dashboardBody(
# to perform to use a set of parameters already tested on serveral projects for the numerous software used to perform the clustering and the annotation.
# to perform an uptodate analysis considering the scientific litterature."
))),
fluidRow(directoryInput('directory', label = 'select a directory')),
br(),
hr(),
HTML('<center><h2 style="color:#053383;"><b>Start your analysis</b></h2></center>'),
hr(),
fluidRow(
column(width=2),
column(width=8,
box(title="About",width = 12, status = "primary",
column(width=6, radioButtons("DataTypeMasque",label = "Type of data",choices = c("16S/18S" = "16S_18S","23S/28S" = "23S_28S","ITS" = "ITS"),inline = TRUE)),
column(width=6, radioButtons("PairedOrNot",label = "Paired-end sequencing ?",choices = c('Yes'="y","No"="n"),selected = "n",inline = TRUE)),
column(width=6, tags$div(title="Enter a valid email address to get your results",textInput("to", "Email address *", value="yyy@xxx"))),
column(width=6, selectizeInput("HostName",label = "Select the host",
choices = c("None"="", "a.stephensi (mosquito)" = "astephensi"," b.taurus (cow)" = "btaurus", "c.familiaris (dog)" = "cfamiliaris",
"chiroptera (bat)" = "chiroptera", "c.sabaeus (Apes)" = "csabaeus" , "d.melanogaster (fly)"="dmelanogaster",
"e.caballus (Horse)" = "ecaballus", "f.catus (cat)" = "fcatus", "hg18 (human)"="hg18", "hg19 (human)"="hg19",
"hg38 (human)" = "hg38", "m.lucifugus (bat)" = "mlucifugus", "mm8 (mouse)"= "mm8", "mm9 (mouse)" = "mm9",
"mm10 (mouse)"="mm10", "p.vampyrus (bat)" = "pvampyrus", "s.scrofa (Boar)" = "sscrofa"))),
column(width=6, tags$div(title="If no, default values are chosen",checkboxInput("primer", "Specify the primer"))),
conditionalPanel(condition="input.primer && input.PairedOrNot=='y'",
column(width=12,
textInput("R1primer",label = "Forward primer",value = "TCGTCGGCAGCGTCAGATGTGTATAAGAGACAGCCTACGGGNGGCWGCAG"),
textInput("R2primer",label = "Reverse primer",value = "GTCTCGTGGGCTCGGAGATGTGTATAAGAGACAGGACTACHVGGGTATCTAATCC")
)
),
conditionalPanel(condition="input.primer && input.PairedOrNot=='n'",
column(width=12,
textInput("primerSingle",label = "Primer",value = "TCGTCGGCAGCGTCAGATGTGTATAAGAGACAGCCTACGGGNGGCWGCAG")
)
)
),
box(title="Directory containing the FastQ files ",width = 12, status = "primary",
column(width=12,verbatimTextOutput("dirSel")),
br(),
column(width=12,
shinyDirButton("dir", "Select a directory", "Upload",buttonType = "primary"),
HTML("&nbsp;"),
actionButton("LoadFiles",'Load',icon=icon("refresh"))
),
conditionalPanel(condition="input.LoadFiles>=1",
br(),
hr(),
br(),
column(width=12,uiOutput("FastQList_out"))
)
),
box(id="box-match",title=" Match the paired files (only for paired-end sequencing)",width = 12, status = "primary",
column(width=6, textInput("R1files",label = "Suffix R1 (Forward)",value = "_R1"),
selectInput("R1filesList",label = "","",multiple =TRUE,selectize=FALSE)),
column(width=6,
textInput("R2files",label = "Suffix R2 (Reverse)",value = "_R2"),
selectInput("R2filesList",label = "","",multiple =TRUE,selectize=FALSE)
),
column(width=12,
actionButton("MatchFiles_button",'Match',icon=icon("exchange"),class="btn-primary",style="color: #fff;"),
HTML("&nbsp;"),
actionButton("RemoveFastQbut_R1R2",'Remove file(s)',icon=icon("remove"))
)
),
div(style = "text-align:center;",actionButton("submit", h4(strong("Check and submit")), icon("chevron-circle-right",class="fa-2x"),class="btn-primary",style = "color: #fff"))
),
column(width=2,
uiOutput("InfoMasque"),
uiOutput("InfoMasqueHowTo")
)
)
),
tabItem(tabName = "Upload",
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment