library(plotly)
library(shiny)
library(shinyBS)
library(shinyjs)
library(shinythemes)
library(data.table)
library(DT)
library(brapirv2)
library(shinyWidgets)
library(httr)
#library(profvis)
options(warn =-1)
options(shiny.maxRequestSize=300*1024^2)
max_brapi_snp_number <- 10000
sepPhased <- "/"
sepUnphased <- "/"
unknownString <- "NA"
if (is.null(options()$brapi.cons)) {
brapisupport <-FALSE
brapi_connections <- NULL
} else {
brapisupport <-TRUE
brapi_connections <- names(options("brapi.cons")$brapi.cons)
}
valid_file<-function(df,lc){
if (lc){
if (all(c("Position","Sample Name","Genotype","Dye")%in%colnames(df))){
return(TRUE)
}else{
return(FALSE)
}
}else{
return(TRUE)
}
}
#### UI ####
ui <- fluidPage(theme = shinytheme("flatly"),
#profvis_ui("profiler"),
shinyjs::useShinyjs(),
title = "snpclust",
shinysky::busyIndicator(wait = 1000, text = NULL),
tags$link(rel = "stylesheet", type = "text/css", href = "custom-div.css"),
tags$style(HTML(".navbar {background-image: linear-gradient(#04519b, #044687 60%, #033769);}")),
tags$style(HTML('
.navbar-nav > li > a, .navbar-brand {
padding-top:1px !important;
padding-bottom:1px !important;
height: 70px;
display: flex;
font-size: 18px;
justify-content: center;
align-items: center;
}')),
tags$style(HTML("
.navbar-nav {
float: none !important;
}
.navbar-nav > li:nth-child(5) {
float: right;
}
")),
navbarPage(title = uiOutput("title_navbar"), id = "tabsetId",
tabPanel("Load data",value = "load",
#navlistPanel(widths = c(1,11),"From",
h4("Load data from file or from BrAPI endpoint:"),
#switchInput("brapiorfile", label = "Click to choose",
# value = ifelse(brapisupport,TRUE,FALSE),
# onLabel = "BrAPI",
# offLabel = "File",labelWidth = 130, onStatus = "success", offStatus = "info"
#),
bsCollapse(id="loadfrom", open="From file",
bsCollapsePanel(title = "From file", style="info",
#tabPanel("File",
h3("Load data from file"),
#fluidRow(
h4("File format"),
checkboxInput('lc', 'LightCycler 96 Format', FALSE),
checkboxInput('intertek_guess', 'Intertek format (will guess number of lines to skip)', FALSE, width = '100%'),
column(width = 2,
radioButtons('sep', 'Separator',
c(Comma=',',
Semicolon=';',
Tab='\t'),
'\t')),
column(2,
radioButtons('quote', 'Quote',
c(None='',
'Double Quote'='"',
'Single Quote'="'"),
'')),
column(2,
radioButtons('dec', 'Decimal separator',
c(Comma=',',
'Point'='.'),
'.')),
column(2,
checkboxInput('header', 'Header', TRUE),
numericInput(inputId = 'skip',label = 'Number of lines to skip',value = 0)),
tags$hr(),
fileInput('file1', 'Choose file to upload'
#accept = c(
# 'text/csv',
# 'text/comma-separated-values',
# 'text/tab-separated-values',
# 'text/plain',
# '.csv',
# '.tsv'
#)
),
tableOutput("df_data_out")
),
bsCollapsePanel(title = "From BrAPI", style="success",
#tabPanel("BrAPI",
h3("Load data from BrAPI endpoint"),
selectizeInput("mainbrapiendpoint","BrAPI end point", choices = brapi_connections),
passwordInput("mainbrapitoken","Token"),
actionButton("connect_brapi","Connect"),
htmlOutput("mainbrapiendpoint_connect_res"),
selectizeInput("brapi_program", "Program", choices = NULL, selected = NULL,
options = list(placeholder = 'Select a database',
onInitialize = I('function() { this.setValue(""); }')
)
),
selectizeInput("brapi_study", "Study", choices = NULL, selected = NULL,
options = list(
placeholder = 'Select a project',
onInitialize = I('function() { this.setValue(""); }'))
),
htmlOutput("retrieve_variants_res")
)
)),
tabPanel("Retrieve Samples information",value = "samples",
h3(
div(style="display:inline-block;",img(src="ibp.png", width="30px"), style="left;"),
div("BMS connection")),
column(width = 3,
selectizeInput("bmsendpoint","BMS end point", choices = brapi_connections),
passwordInput("bmstoken","BMS token"),
actionButton("connect_bms","Connect"),
htmlOutput("connect_res"),
tags$hr(),
#selectizeInput("crop","Crop", choices = NA),
selectizeInput("program","Programme", choices = NULL),
#tags$hr(),
#selectizeInput("sample_list","Sample List", choices = NULL),
#checkboxInput('loop_over_progs', 'Search in all programs', FALSE),
actionButton("fetch_samples","Fetch samples information")
),
column(9,dataTableOutput("samples_info",height = "600px"),
#div(style="display: inline-block;vertical-align:top;",actionButton("special_samples","Toggle selected as special samples")),
div(style="display: inline-block;vertical-align:top;",actionButton("update_samples","Update samples information")),
htmlOutput("update_samp_res")),
# column(2),
# column(2),
#
#checkboxInput('header', 'Header', TRUE),
#numericInput(inputId = 'skip',label = 'Number of lines to skip',value = 0)),
tags$hr()
),
tabPanel("Match Columns",value = "match",
#selectInput("kcol", label = "Identification Column", choices = NA),
selectizeInput("Xcol", label = "X Fluo Column", choices = NA),
selectizeInput("Ycol", label = "Y Fluo Column", choices = NA),
selectizeInput("Ccol", label = "Call Column", choices = NA),
selectizeInput("Pcol", label = "Plate Column", choices = NA),
selectizeInput("Scol", label = "SNP Column", choices = NA),
selectizeInput("Icol", label = "Sample Column", choices = NA),
actionButton(inputId = "ok_matchcol", label = "OK")
),
tabPanel("Clustering",value="clust",
sidebarLayout(
sidebarPanel(
#splitLayout(
selectizeInput("SNP", label = "SNP", choices = "",
options = list(placeholder = 'Select a SNP',
onInitialize = I('function() { this.setValue(""); }')
)),
#actionButton("prevsnp", "<",style='padding:2px; font-size:80%'),
#actionButton("nextsnp", ">",style='padding:2px; font-size:80%'), cellWidths = c("90%","5%","5%"),
#tags$head(tags$style(HTML("
# .shiny-split-layout > div {
# overflow: visible;
# }
# ")))
#),
selectizeInput("Plate", label = "Plate", choices = "", multiple=TRUE,options = list(plugins= list('remove_button'))),
#selectInput("whichcall", label = "Show Call", choices = c("current","new"),selected = "new"),
# radioButtons('whichcall', 'Display Call',
# c(Current='current',
# New='new'),
# 'current'),
switchInput("whichcall2", label = "Switch current/new call",
value = TRUE,
onLabel = "Current",
offLabel = "New", labelWidth = 180, onStatus = "info", offStatus = "warning"),
actionButton(inputId = "copycall", label = "Copy current to new"),
actionButton(inputId = "resetnewcall", label = "Reset new call"),
checkboxInput(inputId = "tetar",label = "Use Theta/R",value = 0),
checkboxInput(inputId = "fixed_ratio",label = "Fixed axes",value = 0),
tags$hr(),
uiOutput("score_buttons"),
tags$br(),
#actionButton(inputId = "updateY", label = "Score as Allele Y", style="color: #fff; background-color: #dc143c; border-color: #2e6da4"),br(),br(),
#actionButton(inputId = "updateH", label = "Score as Heterozygous", style="color: #fff; background-color: #337ab7; border-color: #2e6da4"),#br(),br(),
#actionButton(inputId = "updateX", label = "Score as Allele X", style="color: #fff; background-color: #3cb371; border-color: #2e6da4"),br(),br(),
actionButton(inputId = "updateU", label = "Score as Missing", style="color: #fff; background-color: #ff7f50; border-color: #ff7f50"),#br(),br(),
actionButton(inputId = "updateN", label = "Score as NTC", style="color: #fff; background-color: #E54FFF; border-color: #E54FFF"),br(),br(),
tags$hr(),
uiOutput("exportData"),
tags$hr(),
bsCollapse(id="adv_geno_seetings", open=NULL,
bsCollapsePanel(title = "Advanced Alleles/genotypes settings", style="primary",
h4("Alleles"),
selectizeInput("snp_x_allele","X Allele", choices = c("A","C","G","T","-","X"), selected="X"),
selectizeInput("snp_y_allele","Y Allele", choices = c("A","C","G","T","-","Y"), selected="Y"),
h4("Genotypes"),
numericInput("ploidy","Ploidy", value = 2, min = 1,max = 5, step = 1),
selectizeInput("allele_sep", "Allele separator",choices=c(":","/","|"), selected = ":"))
)
#downloadButton('downloadData', 'Download new file')
),
mainPanel(
div(style="display: inline-block;vertical-align:middle;",actionButton("prevsnp", "<",style='padding:2px; font-size:100%')),
div(style="display: inline-block;vertical-align:middle;",plotlyOutput("plot", width = 800, height = 600)),
div(style="display: inline-block;vertical-align:middle;",actionButton("nextsnp", ">",style='padding:2px; font-size:100%')),
tags$hr(),
bsCollapse(id="samples_selection", open=NULL,
bsCollapsePanel(title = "Highlight samples", style="primary",
actionButton(inputId = "samples.clearsel", label = "Deselect all"),
dataTableOutput('samples', height = 80)
))
)
)
), tabPanel("About",
h2(a("github",href="https://github.com/jframi/snpclust", target="_blank", icon("github")), align="right"),
h1("snpclust"),
img(src='sticker.png', height="10%", width="10%", align = "right"),
p("snpclust aims at visualizing and manually correct clustering of fluorescence based SNP markers."),
p("It can load data from any kind of text files, or load data from a BrAPI endpoint."),
h2("Contributors"),
p("Jean-François Rami (Maintainer) - rami 'at' cirad.fr"),
p("Alice Boizet (Author) - alice.boizet 'at' cirad.fr"),
img(src='CIRAD_logo.png', height="15%", width="15%", align = "left")
))
)
#### SERVER ####
server <- function(input, output, session) {
#callModule(profvis_server, "profiler")
values <- reactiveValues(df_data = NULL,
newdf = NULL,
samplesdfd = NULL,
toplot=NULL,
xcall=NULL,
ycall=NULL,
hcall=NULL,
cols=NULL,
recols=NULL,
intk_snpinfos=NULL,
snpinfos=NULL,
alls=NULL,
genots=NULL,
main_token=NULL,
bms_token=NULL,
brapi_endpoint_name=NULL,
mainbrapiprogram=NULL,
study_dbid=NULL,
currentSNP=NULL,
targetSNP=NULL,
confirmchangeSNP="none")
output$subtitle <- renderText("snpclust")
output$title_navbar = renderUI(div(img(src="sticker.png", width="60px")))#renderText("snpclust")
scorebts <- reactiveValues()
scorebts$ui <- list()
o <- reactiveVal(list())
parse_GET_param <- reactive({
pars <- parseQueryString(session$clientData$url_search)
})
observeEvent(input$nextsnp,{
if (input$SNP==""){
updateSelectizeInput(session = session, inputId = "SNP", selected = values$snpinfos$SNPID[1])
} else {
updateSelectizeInput(session = session, inputId = "SNP", selected = values$snpinfos$SNPID[which(values$snpinfos$SNPID==input$SNP)+1])
}
})
observeEvent(input$prevsnp,{
if (input$SNP==""){
updateSelectizeInput(session = session, inputId = "SNP", selected = tail(values$snpinfos$SNPID,1))
} else {
updateSelectizeInput(session = session, inputId = "SNP", selected = values$snpinfos$SNPID[which(values$snpinfos$SNPID==input$SNP)-1])
}
})
observeEvent(parse_GET_param(),{
values$main_token <- parse_GET_param()$maintoken
values$bms_token <- parse_GET_param()$bmstoken
values$brapi_endpoint_name <- parse_GET_param()$brapiendpointname
### set up connection
#parsed_url <- parse_api_url(parse_GET_param()$apiURL)
if (!is.null(values$main_token)){
updateTextInput(session = session, inputId = "mainbrapitoken", value = values$main_token)
}
if (!is.null(values$bms_token)){
updateTextInput(session = session, inputId = "bmstoken", value = values$bms_token)
}
if (!is.null(values$brapi_endpoint_name)){
updateTextInput(session = session, inputId = "mainbrapiendpoint", value = values$brapi_endpoint_name)
}
if (!is.null( parse_GET_param()$mainapiURL)){
parsed_url <- parse_api_url(parse_GET_param()$mainapiURL)
values$maincon <- brapirv2::brapi_connect(
secure = TRUE,
protocol = parsed_url$brapi_protocol,
db = parsed_url$brapi_db,
port = parsed_url$brapi_port,
apipath = parsed_url$brapi_apipath,
multicrop = FALSE,
token = parse_GET_param()$maintoken,
granttype = "token",
clientid = "brapir",
bms = FALSE
)
if (!is.null(parse_GET_param()$mainbrapiprogram)){
values$mainbrapiprogram <- parse_GET_param()$mainbrapiprogram
output$exportData <- renderUI({
actionButton(inputId = "pushtobrapi",label = paste0("Save data to ",values$mainbrapiprogram), icon = icon(name = "cloud-upload-alt"))
})
}
if (!is.null(parse_GET_param()$mainbrapistudy)){
values$study_dbid <- parse_GET_param()$mainbrapistudy
values$study_name <- tryCatch(unique(brapirv2::brapi_get_studies(values$maincon, studyDbId = htmltools::urlEncodePath(values$study_dbid))$studyName))
}
if (!is.null( parse_GET_param()$mainapiURL) & !is.null(parse_GET_param()$mainbrapiprogram) & !is.null(parse_GET_param()$mainbrapistudy)){
values$brapi_variantsets <<- tryCatch(brapirv2::brapi_get_variantsets(values$maincon, studyDbId = htmltools::urlEncodePath(values$study_dbid)), error=function(e) e)
values$brapi_variantsetsIds <- unique(values$brapi_variantsets$variantSetDbId)
values$brapi_variantsetsIds <- values$brapi_variantsetsIds[!is.na(values$brapi_variantsetsIds)]
values$brapi_variants <<- do.call(rbind,
lapply(values$brapi_variantsetsIds,
function(a) tryCatch({
# this is a patch to variantSetDbId field missing in gigwa's get variants response
data.table(variantSetDbId=a,brapirv2::brapi_get_variants(values$maincon, variantSetDbId = htmltools::urlEncodePath(a), pageSize = max_brapi_snp_number))
},error=function(e) e)
)
)
values$snpinfos <- values$brapi_variants[,.(SNPID=variantNames, AlleleX=referenceBases, AlleleY=alternateBases)]
#updateSelectizeInput(session, inputId = "SNP", choices = data.frame(label=brapi_variants$variantNames, value=brapi_variants$variantDbId), server = T)
updateSelectizeInput(session, inputId = "SNP", choices = values$brapi_variants$variantNames, server = T, selected = "")
if (nrow(values$brapi_variants)==max_brapi_snp_number){
output$retrieve_variants_res = renderUI(HTML(paste("Found more than ",max_brapi_snp_number," variants:", paste(values$brapi_variants$variantNames[1:10],collapse = ", "), "...</br>", "Keeping only the first ",max_brapi_snp_number," variants")))
}else{
output$retrieve_variants_res = renderText({paste("Found", nrow(values$brapi_variants), "variants:", paste(values$brapi_variants$variantNames[1:10],collapse = ", "), "...")})
}
hideTab(inputId = "tabsetId", target = "load")
hideTab(inputId = "tabsetId", target = "samples")
hideTab(inputId = "tabsetId", target = "match")
output$title_navbar <- renderUI(list(div(div(img(src="sticker.png", width="60px")),
div(HTML(paste0("<p style='font-size:10px; '><br/><br/>connected via BrAPI<br/>endpoint: ",
paste0(parsed_url$brapi_protocol,parsed_url$brapi_db),
"<br/>program: ",
values$mainbrapiprogram,
"<br/>study: ",
values$study_name,
"</p>"))), style="display:flex")))
updateNavbarPage(inputId = "tabsetId", selected = "clust")
brapisupport <<- TRUE
#updateSwitchInput(session = session, inputId = "brapiorfile", value = TRUE)
updateCollapse(session, id="loadfrom", open="From BrAPI", close = "From file")
}
}
})
observeEvent(input$lc,{
if (input$lc){
updateRadioButtons(session,inputId = "sep",selected = '\t')
updateRadioButtons(session,inputId = "quote",selected = '')
updateRadioButtons(session,inputId = "dec",selected = '.')
updateCheckboxInput(session,inputId = "header", value=T)
updateNumericInput(session, inputId = "skip", value = 0)
}
})
# "mainbrapiendpoint"
# "mainbrapitoken"
#observeEvent(input$brapiorfile,{
# if (input$brapiorfile){
# if(input$loadfrom=="From file"){
# updateCollapse(session, id="loadfrom", open="From BrAPI", close = "From file")
# }
# hideTab(inputId = "tabsetId", target = "samples")
# hideTab(inputId = "tabsetId", target = "match")
# output$exportData <- renderUI({
# actionButton(inputId = "pushtobrapi",label = "Save data to BrAPI endpoint", icon = icon(name = "cloud-upload-alt"))
# })
# if (!brapisupport){
# showNotification("To use BrAPI end-points, a list of brapi connections needs to be defined with options(brapi.cons= list(Connection1= brapirv2::brapi_connect(...))) before running the app", type="error",closeButton = TRUE, duration = NULL)
# #updateSwitchInput(session = session, inputId = "brapiorfile", value = FALSE)
# }
# }else{
# if(input$loadfrom=="From BrAPI"){
# updateCollapse(session, id="loadfrom", open="From file", close = "From BrAPI")
# }
# output$exportData <- renderUI({
# downloadButton('downloadData', 'Download recoded file')
# })
#
# showTab(inputId = "tabsetId", target = "samples")
# showTab(inputId = "tabsetId", target = "match")
# }
#})
observeEvent(input$loadfrom,{
if(input$loadfrom=="From file"){
showTab(inputId = "tabsetId", target = "samples")
showTab(inputId = "tabsetId", target = "match")
output$exportData <- renderUI({
downloadButton('downloadData', 'Download recoded file')
})
}
if(input$loadfrom=="From BrAPI"){
hideTab(inputId = "tabsetId", target = "samples")
hideTab(inputId = "tabsetId", target = "match")
if (!is.null(values$mainbrapiprogram)){
output$exportData <- renderUI({
actionButton(inputId = "pushtobrapi",label = paste0("Save data to ",values$mainbrapiprogram), icon = icon(name = "cloud-upload-alt"))
})
}else{
output$exportData <- renderUI({
actionButton(inputId = "pushtobrapi",label = "Save data to BrAPI endpoint", icon = icon(name = "cloud-upload-alt"))
})
}
if (!brapisupport){
showNotification("To use BrAPI end-points, a list of brapi connections needs to be defined with options(brapi.cons= list(Connection1= brapirv2::brapi_connect(...))) before running the app", type="error",closeButton = TRUE, duration = NULL)
#updateSwitchInput(session = session, inputId = "brapiorfile", value = FALSE)
}
}
})
observeEvent(input$connect_brapi,{
if (input$mainbrapiendpoint!=""){
values$maincon <- options()$brapi.cons[[input$mainbrapiendpoint]]
values$maincon$token <- input$mainbrapitoken
brapidbs <<- tryCatch(brapirv2::brapi_get_programs(values$maincon),
error=function(e) e)
# For offline testing
#progs <<- data.table(name="toto")
if ("error"%in%class(brapidbs)){
output$mainbrapiendpoint_connect_res = renderText({paste("<span style=\"color:red\">Connection failed</span>")})
}else {
if (input$mainbrapitoken==""){
output$mainbrapiendpoint_connect_res = renderText({paste("<span style=\"color:green\">Connection succeeded (No token provided, listing public datasets)</span>")})
}else{
output$mainbrapiendpoint_connect_res = renderText({paste("<span style=\"color:green\">Connection succeeded</span>")})
}
updateSelectizeInput(session, "brapi_program",choices = brapidbs$programDbId)
}
}
})
observeEvent(input$brapi_program,{
if (input$mainbrapiendpoint!="" & input$brapi_program!=""){
#values$maincon <<- options()$brapi.cons[[input$mainbrapiendpoint]]
#values$maincon$token <<- input$mainbrapitoken
brapi_studies <<- tryCatch(brapirv2::brapi_get_studies(values$maincon, trialDbId=input$brapi_program),
error=function(e) e)
updateSelectizeInput(session, "brapi_study",choices = brapi_studies$studyName, selected = NULL)
output$exportData <- renderUI({
actionButton(inputId = "pushtobrapi",label = paste0("Save data to ",input$brapi_program), icon = icon(name = "cloud-upload-alt"))
})
}
})
observeEvent(input$brapi_study,{
if (input$mainbrapiendpoint!="" & input$brapi_program!="" & input$brapi_study!=""){
#values$maincon <<- options()$brapi.cons[[input$mainbrapiendpoint]]
#values$maincon$token <<- input$mainbrapitoken
values$study_dbid <- brapi_studies[brapi_studies$studyName==input$brapi_study, "studyDbId"]
values$brapi_variantsets <<- tryCatch(brapirv2::brapi_get_variantsets(values$maincon, studyDbId = htmltools::urlEncodePath(values$study_dbid)), error=function(e) e)
values$brapi_variantsetsIds <- unique(values$brapi_variantsets$variantSetDbId)
values$brapi_variantsetsIds <- values$brapi_variantsetsIds[!is.na(values$brapi_variantsetsIds)]
values$brapi_variants <<- do.call(rbind,
lapply(values$brapi_variantsetsIds,
function(a) tryCatch({
# this is a patch to variantSetDbId field missing in gigwa's get variants response
data.table(variantSetDbId=a,brapirv2::brapi_get_variants(values$maincon, variantSetDbId = htmltools::urlEncodePath(a), pageSize = max_brapi_snp_number))
},error=function(e) e)
)
)
values$snpinfos <- values$brapi_variants[,.(SNPID=variantNames, AlleleX=referenceBases, AlleleY=alternateBases)]
#updateSelectizeInput(session, inputId = "SNP", choices = data.frame(label=brapi_variants$variantNames, value=brapi_variants$variantDbId), server = T)
updateSelectizeInput(session, inputId = "SNP", choices = values$brapi_variants$variantNames, server = T, selected = "")
if (nrow(values$brapi_variants)==max_brapi_snp_number){
output$retrieve_variants_res = renderUI(HTML(paste("Found more than ",max_brapi_snp_number," variants:", paste(values$brapi_variants$variantNames[1:10],collapse = ", "), "...</br>", "Keeping only the first ",max_brapi_snp_number," variants")))
}else{
output$retrieve_variants_res = renderText({paste("Found", nrow(values$brapi_variants), "variants:", paste(values$brapi_variants$variantNames[1:10],collapse = ", "), "...")})
}
}
})
observe( {
inFile <- input$file1
if (!is.null(inFile)){
#df<-read.table(inFile$datapath, header = input$header,
# sep = input$sep, quote = input$quote, skip = input$skip, dec = input$dec, stringsAsFactors = F)
if (input$intertek_guess){
rawfile<-scan(inFile$datapath, what = "character", sep = "\n",blank.lines.skip= F, quiet = T)
updateNumericInput(session, "skip", value = grep("^Data$",rawfile))
updateRadioButtons(session, "sep",selected = ",")
snpinforow <- grep("^SNPs$",rawfile)
snpinforow_end <- grep("^Scaling$",rawfile)-2
values$intk_snpinfos <- fread(inFile$datapath, header = input$header, sep = ",", quote = input$quote, skip = snpinforow, nrows = snpinforow_end-snpinforow)
} else {
updateNumericInput(session, "skip", value = 0)
}
df<-fread(inFile$datapath, header = input$header,
sep = input$sep, quote = input$quote, skip = input$skip, dec = input$dec, stringsAsFactors = F)
if(!valid_file(df,input$lc)){
showModal(modalDialog("File doesn't look like a LightCycler file"))
} else{
if (input$lc){
df<-df[EPF!="-"]
df$EPF<-as.numeric(df$EPF)
DF<-df
dyes<-unique(DF$Dye)
#browser()
DF<-DF[,.(Dyes=paste(Dye,collapse = "/"),X.Fluor=EPF[1],Y.Fluor=EPF[2],Call=Genotype[1],`Sample Name`=`Sample Name`[1],Notes=Notes[1],`Sample Prep Notes`=`Sample Prep Notes`[1]),Position]
DF[Call==paste0("Homozygote: ",dyes[1]),Call:="Allele_X"]
DF[Call==paste0("Homozygote: ",dyes[2]),Call:="Allele_Y"]
DF[Call=="Heterozygote",Call:="Both_Alleles"]
DF[Call=="-",Call:="Unknown"]
DF[,Experiment_Name:=input$file1$name]
values$df_data <- data.frame(DF)
values$samplesdfd <- NULL
}else{
values$df_data <- data.frame(df) #data.table(df)
values$samplesdfd <- NULL
}
}
}
})
observeEvent(input$connect_bms,{
bmscon <<- options()$brapi.cons[[input$bmsendpoint]]
if (!is.null(input$bmstoken)){
bmscon$token <<- input$bmstoken
progs <<- tryCatch(setDT(brapirv2::brapi_get_programs(bmscon, commonCropName = bmscon$commoncropname)),
error=function(e) e)
if ("error"%in%class(progs)){
output$connect_res = renderText({paste("<span style=\"color:red\">Connection failed</span>")})
}else {
output$connect_res = renderText({paste("<span style=\"color:green\">Connection succeeded</span>")})
updateSelectizeInput(session, "program",choices = progs$programName, selected = progs$programName[1])
}
}
})
observe({
if (input$program!=""){
#selprogUUID <- progs[programName==input$program,programDbId]
#samplelists <<- bmsapi_Get_sample_list_search(bmscon, crop = bmscon$commoncropname, programUUID = selprogUUID)
# updateSelectizeInput(session, "sample_list",choices = samplelists$listName)
}
})
observeEvent(input$fetch_samples,{
if (input$program!=""){
# if (input$loop_over_progs == TRUE){
# progs_search <- progs$programDbId
# } else {
# progs_search <- progs[programName==input$program,programDbId]
# }
# samples <- data.table(NULL)
# for (pgDbId in progs_search){
# samplelists <- bmsapi_Get_sample_list_search(bmscon, crop = bmscon$commoncropname, programUUID = pgDbId)
# for (l in 1:nrow(samplelists)){
# samp <- bmsapi_Get_sample_list_download(con = bmscon,
# crop = bmscon$commoncropname,
# programUUID = pgDbId,
# listId = samplelists[l, id],
# listName = samplelists[l, listName])
# samples <- rbind(samples,samp)
# }
# }
sidslookup <- unique(values$df_data$SubjectID)
sidslookup <- sidslookup[sidslookup!=""]
sampsrchid <- brapi_post_search_samples(con = bmscon, sampleDbIds = sidslookup)
samps <- brapi_get_search_samples_searchResultsDbId(con = bmscon, searchResultsDbId = sampsrchid$searchResultsDbId)
nbpages <- attr(samps, which = "pagination")$totalPages
if (nbpages > 1){
samps <- rbind(samps, do.call(rbind,
lapply(1:(nbpages-1),
function(p) brapi_get_search_samples_searchResultsDbId(con = bmscon, searchResultsDbId = sampsrchid$searchResultsDbId, page = p)
)
)
)
}
setDT(samps)
samples <- unique(samps[,.(sampleDbId,sampleName,germplasmDbId)])
}
dfd<-unique(data.table(values$df_data)[,.(SubjectID, Found=FALSE)])
samplesdfd<-samples[dfd, on=c(sampleDbId="SubjectID")]
samplesdfd[!is.na(germplasmDbId), Found:=TRUE]
output$update_samp_res = renderText({paste("<span style=\"color:green\">",nrow(samplesdfd[!is.na(germplasmDbId)]),"samples found out of ",nrow(samplesdfd)," samples. Use the 'Found' column to identify missing samples</span>")})
values$samplesdfd <- samplesdfd
})
#observeEvent(input$special_samples,{
# samplesdfd<-copy(values$samplesdfd)
# samplesdfd[input$samples_info_rows_selected, Special:=!Special]
# values$samplesdfd<-samplesdfd
#})
observe({
if(!is.null(values$samplesdfd)){
isolate(s <- input$samples_rows_selected)
output$samples <- DT::renderDataTable(DT::datatable(values$samplesdfd,
class="compact",
filter = list(position='top', clear=F),
escape = F,
rownames = F,
extension = c("Scroller"),
selection = list(mode = 'multiple', selected = s),
option = list(
scrollX = T, scrollY = 450, scrollCollapse = F, scroller = T,
dom = 'Blfrtip'#,
#buttons = list(list(extend='selectAll',className='selectAll',
# text="Select All",
# action=DT::JS("function () {
# var table = $('.dataTable').DataTable();
# table.rows({ search: 'applied'}).deselect();
# table.rows({ search: 'applied'}).select();}")),
# list(extend='selectNone',
# text="Deselect All",
# action=DT::JS("function () {
# var table = $('.dataTable').DataTable();
# table.rows({ search: 'applied'}).select();
# table.rows({ search: 'applied'}).deselect();}")))
)
), server = TRUE)
dtproxy <<- dataTableProxy('samples')
}
})
observeEvent(input$update_samples,{
dfd <- data.table(values$df_data)
dfd <- values$samplesdfd[,.(sampleDbId,sampleName,germplasmDbId)][dfd, on=c(sampleDbId="SubjectID")]
setnames(dfd,old = "sampleDbId",new = "SubjectID")
dfd [!is.na(germplasmDbId), Sample_Plot_Label:=paste0(sampleName," - GUID:",germplasmDbId)]
dfd [is.na(Sample_Plot_Label), Sample_Plot_Label:=SubjectID]
values$df_data <- dfd[,c(colnames(values$df_data),"Sample_Plot_Label"), with=F]
output$update_samp_res = renderText({paste("<span style=\"color:green\">Samples information updated: use the Sample_Plot_Label column as Sample Column at next step</span>")})
updateSelectizeInput(session, inputId = "Icol", selected = "Sample_Plot_Label")
updateNavbarPage(session, "tabsetId", selected = "match")
})
output$samples_info<-renderDataTable({
datatable(
{values$samplesdfd},
filter = list(position='top', clear=F),
escape = F,
rownames = F,
extension = c("Scroller"),
selection = 'multiple',
option = list(
scrollX = T, scrollY = 450, scrollCollapse = F, scroller = T,
dom = 'Brti'
))
})
observe({
updateSelectizeInput(session, "Xcol",choices = colnames(values$df_data), selected = "X")
updateSelectizeInput(session, "Ycol",choices = colnames(values$df_data), selected = "Y")
updateSelectizeInput(session, "Ccol",choices = c("",colnames(values$df_data)), selected = "Call")
updateSelectizeInput(session, "Pcol",choices = c("",colnames(values$df_data)), selected = "MasterPlate")
updateSelectizeInput(session, "Scol",choices = c("",colnames(values$df_data)), selected = "SNPID")
updateSelectizeInput(session, "Icol",choices = c("",colnames(values$df_data)), selected = sort(colnames(values$df_data)[colnames(values$df_data)%in%c("Sample_Plot_Label","SubjectID")])[1])
#updateSelectInput(session, "kcol",choices = colnames(values$df_data), selected = "order")
})
observeEvent(input$ok_matchcol,{
temp<-values$df_data
#browser()
if (input$Ccol==""){
temp<-data.frame(temp,Call="Unknown", stringsAsFactors = F)
}else{
colnames(temp)[match(input$Ccol,colnames(temp))]<-"Call"
}
if (input$Pcol==""){
temp<-data.frame(temp,Plate="Any Plate", stringsAsFactors = F)
}else{
colnames(temp)[match(input$Pcol,colnames(temp))]<-"Plate"
}
if (input$Scol==""){
temp<-data.frame(temp,SNP="Any SNP", stringsAsFactors = F)
}else{
colnames(temp)[match(input$Scol,colnames(temp))]<-"SNP"
}
if (input$Icol==""){
temp<-data.frame(temp,SampName="", stringsAsFactors = F)
}else{
colnames(temp)[match(input$Icol,colnames(temp))]<-"SampName"
}
colnames(temp)[match(c(input$Xcol,input$Ycol),colnames(temp))]<-c("X.Fluor","Y.Fluor")
if (!any(colnames(temp)=="NewCall")){
temp<-data.frame(temp,NewCall="Unknown", stringsAsFactors = F)
}
if (!any(colnames(temp)=="snpclustId")){
temp<-data.frame(temp, snpclustId = c(1:nrow(temp)), stringsAsFactors = F)
}
#temp$X.Fluor<-temp$X.Fluor-min(temp$X.Fluor)
#temp$Y.Fluor<-temp$Y.Fluor-min(temp$Y.Fluor)
if (any(temp$Call%in%c("?","NA", "Uncallable", "Negative"))){
temp[temp$Call%in%c("?","NA", "Uncallable", "Negative"),]$Call <- NA
}
values$newdf<-temp
updateSelectizeInput(session, "Plate",choices = sort(unique(temp$Plate)))
updateSelectizeInput(session, "SNP",choices = sort(unique(temp$SNP)))
updateNavbarPage(session, "tabsetId", selected = "clust")
if (input$intertek_guess){
values$snpinfos <- values$intk_snpinfos[,.(SNPID,AlleleX, AlleleY)]
} else {
# Try to figure out what are the alleles from the data
T <- data.table(temp)
T[,c("Allele1","Allele2"):=tstrsplit(Call, split="[:/|]")]
TT<- melt(T, id.vars = c( "SNP",
"SampName",
"X.Fluor",
"Y.Fluor",
"Call",
"Plate",
"NewCall",
"snpclustId"),
variable.name = "AlleleNb",
value.name = "Allele")
TT <- TT[Allele%in%c("A","C","G","T")]
TTT <- TT[,.(X.mean=mean(X.Fluor),Y.mean=mean(Y.Fluor)),.(SNP,Allele)]
TTTT <- TTT[,.(AlleleX=Allele[which.max(X.mean)],AlleleY=Allele[which.max(Y.mean)]), .(SNPID=SNP)]
#values$snpinfos <- data.table(SNPID=unique(temp$SNP), AlleleX="X", AlleleY="Y")
values$snpinfos <- TTTT
}
})
observeEvent(input$Plate,{
temp<-values$newdf
selSNP<-input$SNP
if (input$loadfrom=="From BrAPI"){
if (!is.null(input$Plate)){
if (input$SNP!=""){
values$toplot<-values$newdf[values$newdf$SNP==selSNP & values$newdf$Plate%in%input$Plate,]
}
}else{
if (input$SNP!=""){
values$toplot<-values$newdf[values$newdf$SNP==input$SNP,]
}
}
} else {
if (!is.null(input$Plate)){
updateSelectizeInput(session, "SNP",selected=selSNP , choices = unique(temp[temp$Plate%in%input$Plate,"SNP"]),label = paste("SNP (Plates:",paste(input$Plate, collapse = ","),")",sep=""))
#if (!is.null(input$Plate)){
# values$toplot<-values$newdf[values$newdf$Plate%in%input$Plate,]
#}
if (input$SNP!=""){
values$toplot<-values$newdf[values$newdf$SNP==input$SNP & values$newdf$Plate%in%input$Plate,]
}
} else{
updateSelectizeInput(session, "SNP",selected=selSNP , choices = unique(temp[,"SNP"]),label = "SNP")
updateSelectizeInput(session, "Plate" , choices = unique(temp[,"Plate"]))
if (input$SNP!=""){
values$toplot<-values$newdf[values$newdf$SNP==input$SNP,]
}
}
}
},ignoreNULL = FALSE)
observeEvent(input$confirmchangeSNP, {
values$confirmchangeSNP <- "yes"
updateSelectizeInput(session = session, inputId = "SNP", selected = values$targetSNP)
removeModal()
})
observeEvent(input$cancelchangeSNP, {
values$confirmchangeSNP <- "cancel"
updateSelectizeInput(session = session, inputId = "SNP", selected = values$currentSNP)
removeModal()
})
observeEvent(c(input$SNP,input$confirmchangeSNP),{
if (values$confirmchangeSNP=="none" & input$loadfrom=="From BrAPI" & !all(values$newdf[,"NewCall"]=="Unknown") & any(!values$newdf[,"Call"]==values$newdf[,"NewCall"])){
values$targetSNP <- input$SNP
showModal(modalDialog(
"Some SNP calls have been changed. Changing to a different SNP without saving will discard changes. Are you sure you want to proceed?",
footer = tagList(actionButton("confirmchangeSNP", "Yes"),
actionButton("cancelchangeSNP", "Cancel")
)
))
} else {
if (values$confirmchangeSNP!="cancel"){
temp<-values$newdf
selplate<-input$Plate
values$currentSNP <- input$SNP
if (input$SNP!=""){
updateSelectizeInput(session, "Plate", selected=selplate, choices = sort(unique(temp[temp$SNP==input$SNP,"Plate"])),label = paste("Plate (SNP:",input$SNP,")",sep=""))
} else{
updateSelectizeInput(session, "Plate", selected=selplate, choices = sort(unique(temp[,"Plate"])),label = "Plate")
}
if (input$SNP!=""){
if (input$loadfrom=="From BrAPI"){
brapi_variantsets <<- tryCatch(brapirv2::brapi_get_variantsets(values$maincon, studyDbId = htmltools::urlEncodePath(values$study_dbid)), error=function(e) e)
setDT(brapi_variantsets)
brapi_variantsetsIds <- unique(brapi_variantsets$variantSetDbId)
brapi_variantsetsIds <- brapi_variantsetsIds[!is.na(brapi_variantsetsIds)]
brapi_calls <<- do.call(rbind,
lapply(brapi_variantsetsIds,
function(a) tryCatch({
variants <- values$brapi_variants[variantNames==input$SNP & variantSetDbId==a,variantDbId]
if (length(variants)>0){
cs_count <- unique(brapi_variantsets[,.(callSetCount,variantSetDbId)])[variantSetDbId==a,callSetCount]
brapi_get_calls_fast(values$maincon, variantDbId = htmltools::urlEncodePath(variants), variantSetDbId = htmltools::urlEncodePath(a), expandHomozygotes = TRUE, sepPhased = sepPhased, sepUnphased = sepUnphased, unknownString = unknownString, pageSize = as.numeric(cs_count)+1)
}
},error=function(e) e)
)
)
setDT(brapi_calls)
#brapi_calls[nchar(genotype.values)==1 & genotype.values%in%c("A","C","G","T","N","-"), genotype.values:=paste0(genotype.values,"/",genotype.values)]
if (any(colnames(brapi_calls)=="genotypeMetadata.fieldAbbreviation")){
brapi_calls <- brapi_calls[genotypeMetadata.fieldAbbreviation=="FI" & !is.na(genotypeMetadata.fieldValue)]
if (nrow(brapi_calls)>0){
cs <- suppressMessages(brapi_post_search_callsets_fast(values$maincon, callSetDbIds = brapi_calls$callSetDbId))
sps <- suppressMessages(brapi_post_search_samples_fast(values$maincon, sampleDbIds = cs$sampleDbId, pageSize = length(cs$sampleDbId)))
setDT(cs)
setDT(sps)
if (nrow(sps)>0){
values$samplesdfd <- sps[cs, on=.(sampleDbId)]
} else {
values$samplesdfd <- cs
values$samplesdfd[, sampleName:=NA]
}
brapi_calls <- cbind(brapi_calls, brapi_calls[, tstrsplit(genotypeMetadata.fieldValue, split=",", names = c("X.Fluor","Y.Fluor"))])
brapi_calls[, X.Fluor:=as.numeric(X.Fluor)]
brapi_calls[, Y.Fluor:=as.numeric(Y.Fluor)]
brapi_calls[, snpclustId:=1:.N]
brapi_calls[, NewCall:="Unknown"]
if (any(grepl("[M,m]aster[[:blank:]]*[P,p]late",colnames(values$samplesdfd)))){
platecol <- grep("[M,m]aster[[:blank:]]*[P,p]late",colnames(values$samplesdfd), value = T)[1]
brapi_calls <- values$samplesdfd[,c("callSetDbId",platecol), with=FALSE][brapi_calls, on=.(callSetDbId)]
brapi_calls[, Plate:=NA]
brapi_calls$Plate <- brapi_calls[[platecol]]
} else {
brapi_calls[, Plate:=NA]
}
brapi_calls[, variantName:=input$SNP]
brapi_calls[, callSetName:=callSetDbId]
brapi_calls <- brapi_calls[values$samplesdfd, on=.(callSetDbId)]
values$samplesdfd <- brapi_calls[,.(callSetDbId,Call=genotypeValue)][values$samplesdfd,on=.(callSetDbId)]
#brapi_calls[,genotypeValue:=unlist(genotypeValue)]
setnames(brapi_calls,
old=c("variantName",
"genotypeValue",
"callSetDbId",
"sampleName"),
new=c("SNP",
"Call",
"SubjectID",
"SampName"), skip_absent = T)
values$newdf <- data.frame(brapi_calls[,.(SNP, Call,snpclustId, SubjectID, SampName, X.Fluor, Y.Fluor, NewCall, Plate)])
updateSelectizeInput(session = session, inputId = "Plate", choices = sort(unique(values$newdf$Plate)))
}
}else{
values$newdf <- data.frame(SNP="", Call="",snpclustId="", SubjectID="", SampName="", X.Fluor=0, Y.Fluor=0, NewCall="", Plate="")
}
}
if (!is.null(values$newdf)){
values$toplot<-values$newdf
if (!is.null(input$Plate)){
values$toplot<-values$toplot[values$toplot$Plate%in%input$Plate,]
}
if (input$SNP!=""){
values$toplot<-values$toplot[values$toplot$SNP==input$SNP,]
}
calls <- unique(values$toplot$Call)
calls <- calls[!is.na(calls)]
values$cols <- calls
names(values$cols) <- calls
snpinfo <- unique(values$snpinfos[,.(SNPID, AlleleX, AlleleY)])
values$cols[gsub("[:/|]","",calls)==paste(rep(snpinfo[SNPID==input$SNP, AlleleX],2),collapse = "")] <- "#3CB371FF"
values$cols[gsub("[:/|]","",calls)==paste(rep(snpinfo[SNPID==input$SNP, AlleleY],2),collapse = "")] <- "#DC143CFF"
values$cols[gsub("[:/|]","",calls)==paste(c(snpinfo[SNPID==input$SNP, AlleleY],snpinfo[SNPID==input$SNP, AlleleX]),collapse = "")] <- "#00CCC5FF"
values$cols[gsub("[:/|]","",calls)==paste(c(snpinfo[SNPID==input$SNP, AlleleX],snpinfo[SNPID==input$SNP, AlleleY]),collapse = "")] <- "#00CCC5FF"
values$cols[gsub("[:/|]","",calls)=="NTC"] <- "#E54FFF"
values$cols[!grepl("^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6})$",values$cols)] <- "#FF7F50FF"
guess_seps <- gsub("^.*([:/|]).*$","\\1",na.omit(grep("[[:punct:]]",calls, value = T)))
guess_sep <- unique(guess_seps)[which.max(table(guess_seps))]
#$$$
updateSelectizeInput(session = session, inputId = "allele_sep", selected = guess_sep)
updateSelectizeInput(session = session, inputId = "snp_x_allele", selected = snpinfo[SNPID==input$SNP, AlleleX])
updateSelectizeInput(session = session, inputId = "snp_y_allele", selected = snpinfo[SNPID==input$SNP, AlleleY])
}
}
}
values$confirmchangeSNP <- "none"
}
})
observeEvent(input$snp_x_allele,{
if (!is.null(values$snpinfos)){
values$snpinfos <- copy(values$snpinfos[SNPID==input$SNP, AlleleX:=input$snp_x_allele])
}
})
observeEvent(input$snp_y_allele,{
if (!is.null(values$snpinfos)){
values$snpinfos <- copy(values$snpinfos[SNPID==input$SNP, AlleleY:=input$snp_y_allele])
}
})
observe({
if (!is.null(values$snpinfos) & input$SNP!=""){
#values$alls <- c(values$snpinfos[SNPID==input$SNP, AlleleX], values$snpinfos[SNPID==input$SNP, AlleleY])
values$alls <- c(input$snp_x_allele, input$snp_y_allele)
n <- input$ploidy
#values$genots <- unlist(lapply(0:n, function(a) paste(c(rep(values$alls[1],a), rep(values$alls[2],n-a)), collapse = input$allele_sep)))
values$genots <- unlist(lapply(n:0, function(a) paste(c(rep(values$alls[1],a), rep(values$alls[2],n-a)), collapse = "")))
isolate({
values$recols <- c("#3CB371FF", colorRampPalette(c("#00CCC5", "#4E00D6"))(n-1), "#DC143CFF")
#names(values$recols) <- values$genots
names(values$recols) <- unlist(lapply(strsplit(values$genots, split = ""), function(a) paste(a,collapse=input$allele_sep)))
values$recols <- c(values$recols, NTC="#E54FFF", Unknown="grey40")
})
scorebts$ui <- lapply(rev(values$genots), function(g) list(actionButton(inputId = paste0("scoreb",gsub(input$allele_sep,"",g)),
label = paste0("Score as ",paste(unlist(strsplit(g, split = "")), collapse = input$allele_sep)),
style=paste0("color: #fff; background-color: ",values$recols[[which(values$genots==g)]],"; border-color: ",values$recols[[which(values$genots==g)]]))))
output$score_buttons <- renderUI({scorebts$ui})
}
})
observe({
req(!is.null(values$genots))
isolate({
lapply(o(), function(x){x$destroy()})
#inputBtn <- paste0("scoreb", gsub(input$allele_sep,"",values$genots))
inputBtn <- paste0("scoreb", values$genots)
#o(lapply(values$genots, function(x){
o(lapply(inputBtn, function(x){
#observeEvent(input[[paste0("scoreb", gsub(input$allele_sep,"",x))]],{
observeEvent(input[[x]],{
d <- event_data("plotly_selected")
temp<-values$newdf
g <- gsub("scoreb","",x)
temp$NewCall[temp$snpclustId%in%d$key]<- paste(unlist(strsplit(g, split = "")),collapse=input$allele_sep)
values$newdf<-temp
values$toplot<-values$newdf
if (!is.null(input$Plate)){
values$toplot<-values$toplot[values$toplot$Plate%in%input$Plate,]
}
if (input$SNP!=""){
values$toplot<-values$toplot[values$toplot$SNP==input$SNP,]
}
})
}))
})
})
observeEvent(input$copycall,{
temp<-values$newdf
if (!is.null(input$Plate)){
temp[temp$Plate%in%input$Plate & temp$SNP==input$SNP,"NewCall"]<-gsub(" ", "_", temp[temp$Plate%in%input$Plate & temp$SNP==input$SNP,"Call"])
}else{
temp[temp$SNP==input$SNP,"NewCall"]<-gsub(" ", "_", temp[temp$SNP==input$SNP,"Call"])
}
values$newdf<-temp
values$toplot<-values$newdf
if (!is.null(input$Plate)){
values$toplot<-values$toplot[values$toplot$Plate%in%input$Plate,]
}
if (input$SNP!=""){
values$toplot<-values$toplot[values$toplot$SNP==input$SNP,]
}
})
observeEvent(input$resetnewcall,{
temp<-values$newdf
if (!is.null(input$Plate)){
temp[temp$Plate%in%input$Plate & temp$SNP==input$SNP,"NewCall"]<-"Unknown"
}else{
temp[temp$SNP==input$SNP,"NewCall"]<-"Unknown"
}
values$newdf<-temp
values$toplot<-values$newdf
if (!is.null(input$Plate)){
values$toplot<-values$toplot[values$toplot$Plate%in%input$Plate,]
}
if (input$SNP!=""){
values$toplot<-values$toplot[values$toplot$SNP==input$SNP,]
}
})
observeEvent(input$updateX,{
d <- event_data("plotly_selected")
temp<-values$newdf
temp$NewCall[temp$snpclustId%in%d$key]<- values$xcall #"Allele_X"
values$newdf<-temp
values$toplot<-values$newdf
if (!is.null(input$Plate)){
values$toplot<-values$toplot[values$toplot$Plate%in%input$Plate,]
}
if (input$SNP!=""){
values$toplot<-values$toplot[values$toplot$SNP==input$SNP,]
}
})
observeEvent(input$updateY,{
d <- event_data("plotly_selected")
temp<-values$newdf
temp$NewCall[temp$snpclustId%in%d$key]<- values$ycall #"Allele_Y"
values$newdf<-temp
values$toplot<-values$newdf
if (!is.null(input$Plate)){
values$toplot<-values$toplot[values$toplot$Plate%in%input$Plate,]
}
if (input$SNP!=""){
values$toplot<-values$toplot[values$toplot$SNP==input$SNP,]
}
})
observeEvent(input$updateH,{
d <- event_data("plotly_selected")
temp<-values$newdf
temp$NewCall[temp$snpclustId%in%d$key]<- values$hcall #"Both_Alleles"
values$newdf<-temp
values$toplot<-values$newdf
if (!is.null(input$Plate)){
values$toplot<-values$toplot[values$toplot$Plate%in%input$Plate,]
}
if (input$SNP!=""){
values$toplot<-values$toplot[values$toplot$SNP==input$SNP,]
}
})
observeEvent(input$updateU,{
d <- event_data("plotly_selected")
temp<-values$newdf
temp$NewCall[temp$snpclustId%in%d$key]<- "NA"
values$newdf<-temp
values$toplot<-values$newdf
if (!is.null(input$Plate)){
values$toplot<-values$toplot[values$toplot$Plate%in%input$Plate,]
}
if (input$SNP!=""){
values$toplot<-values$toplot[values$toplot$SNP==input$SNP,]
}
})
observeEvent(input$updateN,{
d <- event_data("plotly_selected")
temp<-values$newdf
temp$NewCall[temp$snpclustId%in%d$key]<- "NTC"
values$newdf<-temp
values$toplot<-values$newdf
if (!is.null(input$Plate)){
values$toplot<-values$toplot[values$toplot$Plate%in%input$Plate,]
}
if (input$SNP!=""){
values$toplot<-values$toplot[values$toplot$SNP==input$SNP,]
}
})
output$df_data_out <- renderTable(head(values$df_data))
observe({
if (!is.null(values$newdf)){
if (input$SNP!=""){
ptitle<-paste(ifelse(input$SNP%in%c("","Any SNP"),"",input$SNP))#,ifelse(input$Plate%in%c("","Any SNP"),"",paste("-",paste(input$Plate,collapse = ","))))
s <- input$samples_rows_selected
if (input$tetar == TRUE){
isolate({
if (any(!c("R","Theta")%in%colnames(values$toplot))){
values$toplot<-cbind(values$toplot,xy2ThetaR(values$toplot[,c("X.Fluor","Y.Fluor")]))
}
})
output$plot <- renderPlotly({
# if (input$whichcall2==FALSE){
# cols <- c("Allele_X" = "#3CB371FF", "Allele_Y" = "#DC143CFF", "Both_Alleles" = "#337AB7FF", "NA" = "#FF7F50FF", "Negative"="#808080FF")
# names(cols) <- c(values$xcall,values$ycall,values$hcall,"NA", "Negative" )
# p <- ggplot(values$toplot,aes(x=Theta, y=R, colour=NewCall, key= snpclustId, text=paste("Sample:",SampName))) + geom_point() #+facet_wrap(~Experiment_Name,ncol = 2)
# p <- p + scale_colour_manual(values = cols)
# }else{
# p <- ggplot(values$toplot[values$toplot$Plate%in%input$Plate & values$toplot$SNP==input$SNP,],aes(x=Theta, y=R, colour=Call, key= snpclustId, text=paste("Sample:",SampName))) + geom_point()+ aes(shape=Special) + scale_shape_manual(values =c(Standard=16,Special=11), name="") #+facet_wrap(~Experiment_Name,ncol = 2)
# }
if (input$whichcall2==FALSE){
#cols <- c("Allele_X" = "#3CB371FF", "Allele_Y" = "#DC143CFF", "Both_Alleles" = "#337AB7FF", "NA" = "#FF7F50FF", "Negative"="#808080FF")
#names(cols) <- c(values$xcall,values$ycall,values$hcall,"NA", "Negative" )
#if(any(colnames(values$toplot)=="Special")){
# p <- ggplot(values$toplot,aes(x=Theta, y=R, colour=NewCall, key = snpclustId, text=paste(paste("Sample:",SampName),paste("Call:",Call), sep="\n"))) + geom_point()+ aes(shape=Special) + scale_shape_manual(values = c(Standard=16,Special=11), name="") #+facet_wrap(~Experiment_Name,ncol = 2)
#}else{
p <- ggplot(values$toplot,aes(x=Theta, y=R, colour=NewCall, key = snpclustId, text=paste(paste("Sample:",SampName),paste("Call:",Call), sep="\n")))+ geom_point()
#}
p <- p + scale_colour_manual(values = values$recols, na.value = "#FF7F50FF")
}else{
#if(any(colnames(values$toplot)=="Special")){
# p <- ggplot(values$toplot,aes(x=Theta, y=R, colour=Call, key = snpclustId, text=paste(paste("Sample:",SampName),paste("NewCall:",NewCall), sep="\n"))) + geom_point()+ aes(shape=Special) + scale_shape_manual(values = c(Standard=16,Special=11), name="") + coord_fixed(ratio = 1,xlim = c(0,maxfluo), ylim = c(0,maxfluo)) #+facet_wrap(~Experiment_Name,ncol = 2)
# p <- p + scale_colour_manual(values = values$cols, na.value = "#FF7F50FF")
#}else{
p <- ggplot(values$toplot,aes(x=Theta, y=R, colour=Call, key = snpclustId, text=paste(paste("Sample:",SampName),paste("NewCall:",NewCall), sep="\n"))) + geom_point() #+facet_wrap(~Experiment_Name,ncol = 2)
p <- p + scale_colour_manual(values = values$cols, na.value = "#FF7F50FF")
#}
}
ggplotly(p+ggtitle(ptitle)) %>% layout(dragmode = "lasso")
})
}else{
#toplot<-values$newdf
#if (!is.null(input$Plate)){
# toplot<-toplot[toplot$Plate%in%input$Plate,]
#}
#if (input$SNP!=""){
# toplot<-toplot[toplot$SNP==input$SNP,]
#}
values$toplot$X.Fluor<-values$toplot$X.Fluor-min(values$toplot$X.Fluor)
values$toplot$Y.Fluor<-values$toplot$Y.Fluor-min(values$toplot$Y.Fluor)
maxfluo<-max(c(values$toplot$X.Fluor,values$toplot$Y.Fluor))
minfluo<-min(c(values$toplot$X.Fluor,values$toplot$Y.Fluor))
output$plot <- renderPlotly({
if (input$whichcall2==FALSE){
#names(cols) <- c(values$xcall,values$ycall,values$hcall,"NA", "Negative" )
#if(any(colnames(values$toplot)=="Special")){
# p <- ggplot(values$toplot,aes(x=X.Fluor, y=Y.Fluor, colour=NewCall, key = snpclustId, text=paste("Sample:",SampName)))+ geom_point()+ aes(shape=Special) + scale_shape_manual(values = c(Standard=16,Special=11), name="") #+facet_wrap(~Experiment_Name,ncol = 2)
#}else{
p <- ggplot(values$toplot,aes(x=X.Fluor, y=Y.Fluor, colour=NewCall, key = snpclustId, text=paste("Sample:",SampName)))+ geom_point()
#}
if (input$fixed_ratio){
p <- p + coord_fixed(ratio = 1, xlim = c(0,maxfluo), ylim = c(0,maxfluo))
}
p <- p + scale_colour_manual(values = values$recols, na.value = "#FF7F50FF")
}else{
#if(any(colnames(values$toplot)=="Special")){
# p <- ggplot(values$toplot,aes(x=X.Fluor, y=Y.Fluor, colour=Call, key = snpclustId, text=paste("Sample:",SampName))) +
# geom_point()+ aes(shape=Special) + scale_shape_manual(values = c(Standard=16,Special=11), name="")
# if (input$fixed_ratio){
# p <- p + coord_fixed(ratio = 1, xlim = c(0,maxfluo), ylim = c(0,maxfluo))
# }
# p <- p + scale_colour_manual(values = values$cols, na.value = "#FF7F50FF")
#}else{
p <- ggplot(values$toplot,aes(x=X.Fluor, y=Y.Fluor, colour=Call, key = snpclustId, text=paste("Sample:",SampName))) + geom_point()
if (input$fixed_ratio){
p <- p + coord_fixed(ratio = 1, xlim = c(0,maxfluo), ylim = c(0,maxfluo))
}
p <- p + scale_colour_manual(values = values$cols, na.value = "#FF7F50FF")
#}
}
if (length(s)){
p <- p + geom_point(data=values$toplot[values$toplot$SubjectID%in%values$samplesdfd[s,]$sampleDbId,], aes(x=X.Fluor, y=Y.Fluor), shape = 21, colour = "#000000ff", size=3)
}
ggplotly(p+ggtitle(ptitle)) %>% layout(dragmode = "lasso")
})
}
}else{
output$plot <- renderPlotly({NULL})
}
}
})
observeEvent(input$samples.clearsel,{
selectRows(dtproxy, selected=NULL)
})
observeEvent(input$pushtobrapi,{
brapicon <- values$maincon
df <- values$newdf
df <- df[df$NewCall != 'Unknown', ]
existingBrapiData <- merge(unique(brapi_calls[,.(callSetDbId, genotypeValue , variantDbId ,variantName ,variantSetDbId)]),
brapi_calls[,list(genotypeMetadata=list(data.table(dataType=genotypeMetadata.dataType,
fieldAbbreviation=genotypeMetadata.fieldAbbreviation,
fieldName=genotypeMetadata.fieldName,
fieldValue=genotypeMetadata.fieldValue))),callSetDbId])
dataToPut <- merge(existingBrapiData, data.table(df)[,.(SubjectID, NewCall)], by.x = "callSetDbId", by.y = "SubjectID")
dataToPut[,genotypeValue:=NULL]
setnames(dataToPut,old = "NewCall",new = "genotypeValue")
body <- list(
expandHomozygotes=jsonlite::unbox("true"),
sepPhased=jsonlite::unbox(sepPhased),
sepUnphased=jsonlite::unbox(sepUnphased),
unknownString=jsonlite::unbox(unknownString),
data=dataToPut
)
#print(jsonlite::toJSON(dataToPut))
jsonBody <- jsonlite::toJSON(body)
brapiPutCallsUrl <- paste0(brapicon$protocol,brapicon$db)
if (brapicon$port != 80) {
brapiPutCallsUrl <- paste0(brapiPutCallsUrl, ":",brapicon$port)
}
brapiPutCallsUrl <- paste0(brapiPutCallsUrl, "/", brapicon$apipath, "/brapi/v2/calls")
#TODO update and use brapirv2
res <- PUT(brapiPutCallsUrl, body = jsonBody, encode = "json", content_type_json(),
add_headers(Authorization=paste0("Bearer ", brapicon$token)))
if (res$status_code == 200) {
showNotification("Calls updated", type="message",closeButton = TRUE, duration = 10)
values$confirmchangeSNP <- "yes"
} else {
showNotification("Error when pushing new calls", type="error",closeButton = TRUE, duration = 10)
}
# showModal(modalDialog(
# "Push of data back to BrAPI endpoint is not yet implemented",
# easyClose = TRUE
# ))
})
output$downloadData <- downloadHandler(
filename = function() {
paste(input$file1$name, '.recoded.txt', sep='')
},
content = function(file) {
write.table(values$newdf, file, sep="\t", col.names = T, row.names = F)
}
)
}
shinyApp(ui, server)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.