#' @title gui
#' @author Oyvind Bleka
#' @description gui is a GUI wrapper (gWidgets) for the MPSproto package
#' @param envirfile A Rdata file including a saved environment of a project
#' @param envir A environment object
#' @export
#library(MPSproto);envirfile=NULL;envir=NULL
gui = function(envirfile=NULL,envir=NULL) {
#size of main window
mwH <- 500
mwW <- 1000
#type of gwidgets-kit
#library(gWidgetstcltk)
options(guiToolkit="tcltk")
pack = "MPSproto" #name of package and program
#version:
version = packageVersion(pack) #follows same version as package number
softname <- paste0(pack," v",version)
#GUI-Restriction on maximum number of contributors
maxKsetup <- 4
CEsep = ":" #CE separator
#Spacing between widgets
spc <- 10
.sep <- .Platform$file.sep # Platform dependent path separator.
pgkPath <- path.package(pack, quiet = FALSE) # Get package path.
#Option files are stored in system (opt-settings): These are default values
optList = list(
optFreq =list(fst=0,freqsize=0,minF=0,normalize=1), #option when new frequencies are found (size of imported database,minFreq), and missmatch options
optMLE = list(nDone=3,delta=1,maxIter=100,maxThreads=0,seed=0,steptol=1e-3,equaltol=0.01), #options when optimizing,validation (nDone,delta)
optDC = list(alphaprob=0.99,maxlist=20), #options when doing deconvolution
optKit = list(platform="MPS",kit="NONE"),
optFreqFile = NULL, #default frequency file
optCalibFile = NULL #default calibration (NEW)
)
configList = list() #list of file name for each element
#TRAVERSE EACH config FILE (configPrefix) AND CHECK IF CONFIG FILE XISTS
for(optName in names(optList) ) {
tmp <- paste0("config",gsub("opt","",optName))
configFile <- configList[[optName]] <- paste0(pgkPath,.sep,tmp)
if( file.exists(configFile) ) { #use default values if not existing
#optF <- scan(file=configFile,what=character(),quiet=TRUE)
optF <- readLines(configFile,warn = FALSE) #,what=character(),quiet=TRUE)
for(i in 1:length(optF)) {
suppressWarnings({
tmp = as.numeric(optF[i])
})
if(is.na(tmp)) tmp = optF[i] #keep original
if(length(tmp)==0) tmp = NULL #no value
optList[[optName]][[i]] = tmp #convert direclty from file
}
if(length(optF)==1) optList[[optName]] = optList[[optName]][[1]]
}
}
#####################
#create environment #
#####################
#Helpfunction to obtain the calibration object
.getCalibrated = function(fn) {
calib = readRDS(fn) #load object
return(calib)
}
if(!is.null(envir)) {
mmTK = envir #use environment direclty
} else if(!is.null(envirfile)) {
load(envirfile) #loading environment
} else { #NEW OBJECT
mmTK = new.env( parent = globalenv() ) #create new envornment object (must be empty)
#Toolbar options: can be changed any time by using toolbar
for(optName in names(optList) ) assign(optName,optList[[optName]],envir=mmTK) #store to envir
#initializing environment variables
assign("workdir",NULL,envir=mmTK) #store work dir
assign("version",NULL,envir=mmTK) #Store version
#Check frequency file and try import it.:
popFreq = NULL #try load frequency data from selected file
if(!is.null( optList$optFreqFile ) ) {
tryCatch({
popFreq = MPSproto::importMPSfreqs( optList$optFreqFile)[[1]]
}, error=function(e) print("System frequency file not valid."))
}
assign("popFreq",popFreq,envir=mmTK) #store frequency in
#Check calibration file and try import it.:
calibrated = NULL #try load calibration data from selected file
if(!is.null( optList$optCalibFile ) ) {
tryCatch({
calibrated = .getCalibrated( optList$optCalibFile )
}, error=function(e) print("System calibration file not valid."))
}
assign("calibrated",calibrated,envir=mmTK)
#imported data:
assign("mixData",NULL,envir=mmTK) #DATA FOR MIXTURES
assign("refData",NULL,envir=mmTK) #DATA FOR REFERENCES
assign("relSettings",NULL,envir=mmTK) #this is settings for relatedness (NOT IMPLEMENTED)
#models: stored setups for model specification
assign("calcList",NULL,envir=mmTK) #store model of calculated results (stored in a table)
#STRUCTURE: calcList[[index]] = list(meta,hd,hp) #hp can be NULL if only deconvolution (POI leaved empty)
#results: stored results after calculations
#assign("resEVID",NULL,envir=mmTK) #assign evidence weighting results (i.e. calculated LR with MLE estimates)
assign("resDC",NULL,envir=mmTK) #assign deconvolved results (i.e. ranked tables of results)
assign("resCompare",NULL,envir=mmTK) #assign information when doing model selection searchs (NOT USED)
}
####################################
#auxiliary functions and variables:#
####################################
#helpfunction to get small number from log-value
.getSmallNumber = function(logval,sig0=2,scientific="e") {
log10base = logval/log(10) #convert to 10 base
power = floor(log10base) #get power number
remainder = log10base - power
return( paste0( round(10^remainder,sig0),scientific,power)) #representation of very small numbers (avoid underflow)
}
.NAtoSign <- function(x) {
x[is.na(x)] <- "-" #NB: New version of gtable does not accept NA values
return(x)
}
# helptext = function(obj,txt) { gWidgets2::addHandlerRightclick(obj,handler=function(h,...) { gWidgets2::gmessage(txt,title="Detailed information") }) }
.helptext = function(obj,txt) { gWidgets2::tooltip(obj) = txt }
#Function to get data from environment
#sel used to select a specific datasubset
.getData = function(type,sel=NULL) {
Data <- NULL
if(type=="mix") Data <- get("mixData",envir=mmTK) #assign kit to mmTK-environment
if(type=="ref") Data <- get("refData",envir=mmTK) #assign kit to mmTK-environment
if(!is.null(sel)) return(Data[sel]) #returns only selected datasubset
return(Data)
}
#function for inserting sample/ref/db-names into existing gWidgets2::gcheckboxgroup
.getDataNames_type = function(type) {
subD <- .getData(type)
if(!is.null(subD)) { return( names(subD))
} else { return("") }
}
#Function which takes rownames and adds to first column
.addRownameTable = function(tab,colname=NULL) {
tmp <- colnames(tab)
tab <- cbind(rownames(tab),tab)
if(is.null(colname)) colname = "X"
colnames(tab) <- c(colname,tmp)
return(tab)
}
#save result table to file:
.saveTable = function(tab,sep="txt") {
tabfile = .mygfile(text="Save table",type="save") #csv is correct format!
if(length(tabfile)==0) return()
if(length(unlist(strsplit(tabfile,"\\.")))==1) tabfile = paste0(tabfile,".",sep)
if(sep=="txt" | sep=="tab") write.table(tab,file=tabfile,quote=FALSE,sep="\t",row.names=FALSE)
if(sep=="csv") write.table(tab,file=tabfile,quote=FALSE,sep=",",row.names=FALSE)
print(paste("Table saved in ",tabfile,sep=""))
} #end file
#Helpfunction to print tables (R v3.5.0) has problem showing tables in the GUI.
.printTable = function(x) {
print(cbind(rownames(x),x),row.names=FALSE)
}
###################################################################
#############GUI HELPFUNCTIONS#####################################
###################################################################
#TAKEN FROM CASESOLVER: This function is written since the encoding in gWidgets2::gfile is fixed to UTF-8 which doesn't handle special letters
.mygfile <- function(text,type,filter=list(),initf=NULL) { #Possible bug: text ignored when type="selectdir"
file <- gWidgets2::gfile(text=text,type=type,filter=filter,initial.filename=initf)
Encoding(file) <- options()$encoding #Set to local encoder: Handle special cases.
return(file)
}
#Helpfunction to get focus
.getFocus = function() {
gWidgets2::visible(mainwin) <- TRUE
gWidgets2::focus(mainwin) <- TRUE
}
#Menu bar file-lists:
.f_setwd = function(h,...) {
dirfile = .mygfile(text="Select folder",type="selectdir")
if(length(dirfile)==0) return()
setwd(dirfile)
assign("workdir",dirfile,envir=mmTK) #assign working directory
}
.f_openproj = function(h,...) {
projfile = .mygfile(text="Open project",type="open", filter=list("Project"=list(patterns=list("*.Rdata")) , "All files"=list(patterns=list("*"))))
if(length(projfile)==0) return()
gWidgets2::dispose(mainwin)
MPSproto::gui(projfile) #send environment into program
}
.f_saveproj = function(h,...) {
projfile = .mygfile(text="Save project",type="save")
if(length(projfile)==0) return()
if(length(unlist(strsplit(projfile,"\\.")))==1) projfile = paste0(projfile,".Rdata") #add extension if missing
# tmp = sort(sapply(mmTK,object.size)/1e6,decreasing=TRUE)
#.selectDataToModel(h=list(action="SAVE")) #store data before saving project
#save(mmTK,file=projfile,compress="xz") #save environment, #Dont compress!
save(mmTK,file=projfile,compress="xz",eval.promises=FALSE,precheck=FALSE,compression_level=2)
print(paste("Project saved in ",projfile,sep=""))
}
.f_quitproj = function(h,...) {
ubool <- gWidgets2::gconfirm("Do you want to save project?",title="Quit Program",icon="info")
if(ubool) {
.f_saveproj(h)
} else {
print("Program terminated without saving")
}
gWidgets2::dispose(mainwin) #remove window!
}
#Throw error message
.NAerror <- function(what) {
gWidgets2::gmessage(paste0(what," must be specified as a valid value"),title="Wrong input",icon="error")
#stop("Wrong user-input")
}
#helpfunction to get value from user
.getValueUser <- function(txt="",val=0) {
val2 <- gWidgets2::ginput(txt, text=val, title="User input",icon="question")
return(val2)
}
#helpfunction to get value in from user and store
#what1="optFreq";what2="fst"
.setValueUser <- function(what1,what2,txt,allowNULL=FALSE,allowText=FALSE) {
listopt <- get(what1,envir=mmTK) #get object what 1.
val <- listopt[[what2]]
if(is.null(val)) val ="" #gwidgets2 does not handle NULL, must use empty string
sw <- gWidgets2::gwindow(title="User input",visible=FALSE, width=300,height=50)
grid <- gWidgets2::glayout(spacing=0,container=sw )
grid[1,1] <- gWidgets2::glabel(txt, container=grid)
grid[1,2] <- gWidgets2::gedit(text=val,container=grid,width=30)
grid[2,1] <- gWidgets2::gbutton("OK", container=grid,handler = function(h, ...) {
GUIval = gWidgets2::svalue(grid[1,2]) #obtain GUI value
if(allowNULL && GUIval=="") { #if accepting empty string
tmp = NULL #Insert NULL
} else {
tmp <- GUIval
if(!allowText) {
tmp <- as.numeric(GUIval) #insert new value
if(is.na(tmp)) {
.NAerror(what2)
return()
}
}
}
listopt[[what2]] <- tmp
assign(what1,listopt,envir=mmTK) #assign user-value to opt-list
write(unlist(listopt),file=configList[[what1]],ncolumns = 1) #store selected values to file
gWidgets2::dispose(sw)
} )
grid[2,2] <- gWidgets2::gbutton("Cancel", container=grid,handler = function(h, ...) { gWidgets2::dispose(sw) } )
gWidgets2::visible(sw) <- TRUE
}
#helpfunction to check value of x
#replaces checkProb,checkPositive,checkPosInteger
.checkValue = function(x,type,what,strict=FALSE) {
if(is.na(x)) .NAerror(what)
isOK = TRUE
if(type=="prob" && (x < 0 || x>1)) isOK = FALSE
if(type=="posInt" && (x < 1 || round(x)!=x)) isOK = FALSE
if(type=="pos") {
if(x < 0) isOK = FALSE
if(strict && x==0) isOK = FALSE
}
if(!isOK) {
switch(type,
prob={msg="must be specified in interval [0,1]"},
pos={msg="must be a positive number"},
posInt={msg="must be a positive integer"}
)
gWidgets2::gmessage(paste0(what," ",msg,""),title="Wrong input",icon="error")
stop("Wrong user-input")
}
}
#helpfunction for printing evidence sample to terminal
.printEvid = function(subD) {
locs <- names(subD) #get unique loci
mixtab <- matrix(ncol=2,nrow=length(locs))
for(loc in locs) { #for each locus
mixA <- subD[[loc]]$adata
mixH <- subD[[loc]]$hdata
if(!is.null(mixA)) mixtab[which(loc==locs),1] <- paste0(mixA ,collapse="/")
if(!is.null(mixH)) mixtab[which(loc==locs),2] <- paste0(mixH ,collapse="/")
}
rownames(mixtab) <- locs
colnames(mixtab) <- c("Allele","Height")
.printTable(mixtab)
}
#helpfunction for printing reference sample to terminal
.printRefs = function(refD,refSel=NULL) {
locs <- unique(unlist(lapply(refD,names))) #get unique loci
reftab <- matrix(ncol=length(refSel),nrow=length(locs)) #last row is RMP
for(rsel in refSel) {
for(loc in locs) { #for each locus
refA <-refD[[rsel]][[loc]]$adata
if(!is.null(refA)) {
reftab[which(loc==locs),which(rsel==refSel)] <- paste0(refA ,collapse="/")
}
}
}
rownames(reftab) <- locs
colnames(reftab) <- refSel
.printTable(reftab)
}
##########################################################################################################################################
#####################################
###########GUI WINDOW STARTS#########
#####################################
##########
#Menu bar#
##########
mblst = list( #project saving and so on
File=list(
gWidgets2::gaction('Set directory',handler=.f_setwd),
gWidgets2::gaction('Open project',handler=.f_openproj),
gWidgets2::gaction('Save project',handler=.f_saveproj),
#gWidgets2::gaction('Settings',handler=.f_settings, action="GLOBAL"),
gWidgets2::gaction('Quit',handler=.f_quitproj,icon="close")
),
Frequencies=list(
gWidgets2::gaction('Set Fst of calculation',handler=function(h,...) { #moved from settings
.setValueUser(what1="optFreq",what2="fst",txt="Set Fst-coefficient")
}),
gWidgets2::gaction('Set size of frequency database',handler=function(h,...) {
.setValueUser(what1="optFreq",what2="freqsize",txt="Set size of imported freq database \n(Min observed used if not spesified):")
}),
gWidgets2::gaction('Set minimum frequency',handler=function(h,...) {
.setValueUser(what1="optFreq",what2="minF",txt="Set minimum freq for new alleles\n(Min observed used if not spesified):")
}),
gWidgets2::gaction('Set whether to normalize frequencies',handler=function(h,...) {
.setValueUser(what1="optFreq",what2="normalize",txt="Should frequencies always add up to one\nafter including rare alleles? (1=YES,0=NO)")
})
),
Optimization=list(
gWidgets2::gaction('Set number of optimizations',handler=function(h,...) {
.setValueUser(what1="optMLE",what2="nDone",txt="Set required number of (identical) optimizations:")
}),
gWidgets2::gaction('Set variation of randomizer',handler=function(h,...) {
.setValueUser(what1="optMLE",what2="delta",txt="Set variance of start point randomizer:")
}),
gWidgets2::gaction('Set max number of iterations',handler=function(h,...) {
.setValueUser(what1="optMLE",what2="maxIter",txt="Set max number of iterations:")
}),
gWidgets2::gaction('Set maximum threads for computation',handler=function(h,...) {
.setValueUser(what1="optMLE",what2="maxThreads",txt="Set max number of threads to be used in parallelisation\n(all used if zero):")
}),
gWidgets2::gaction('Set seed of randomizer',handler=function(h,...) {
.setValueUser(what1="optMLE",what2="seed",txt="Set seed of randomizer\n(Not used if zero):",allowNULL=TRUE)
}),
gWidgets2::gaction('Set accuracy of optimization',handler=function(h,...) {
.setValueUser(what1="optMLE",what2="steptol",txt="Set accuracy of optimization (steptol, see ?nlm):")
})
),
Deconvolution=list(
gWidgets2::gaction('Set required summed probability',handler=function(h,...) {
.setValueUser(what1="optDC",what2="alphaprob",txt="Set required summed posterior genotype-probability of list:")
}),
gWidgets2::gaction('Set max listsize',handler=function(h,...) {
.setValueUser(what1="optDC",what2="maxlist",txt="Set size of maximum elements in deconvoluted list:")
})
)
)
##################################################################################################
########### Program starts #######################################################################
##################################################################################################
#change working directory to the one stored in mmTK-environment
wd=get("workdir",envir=mmTK) #assign working directory to mmTK-environment
if(!is.null(wd) && dir.exists(wd)) setwd(wd)
#Main window:
mainwin <- gWidgets2::gwindow(softname, visible=TRUE, width=mwW,height=mwH)
gWidgets2::gmenu(mblst,container=mainwin)
nb = gWidgets2::gnotebook(container=mainwin)
tabimport0 = gWidgets2::ggroup(horizontal=FALSE,spacing=10,container=nb,label="Data") #tab2: (imports all files)
tabmodel = gWidgets2::glayout(horizontal=FALSE, spacing=spc,container=nb,label="Model") #tab3: specify model used in weight-of-evidence (INT/MLE) or in a Database search
tabMLE = gWidgets2::ggroup(horizontal=FALSE, spacing=spc,container=nb,label="Results")#,expand=T,fill=T) #results from MLE
tabDC = gWidgets2::ggroup(horizontal=FALSE,spacing=spc,container=nb,label="Deconvolution") #results from a deconvolution
####################################################
###############Tab 1: Import Data:##################
####################################################
#When program starts, import assumed model for EVID.
editboxsize = 3 #length of boxes
#b) load/save profiles/database: Supports any filetype
.f_importprof = function(h,...) {
type=h$action #get type of profile
# type = "mix"
# proffile = .mygfile(text=paste("Open ",type,"-file",sep=""),type="open",filter=list("text"=list(patterns=list("*.txt","*.csv","*.tab"))))
proffile = .mygfile(text=paste("Open ",type,"-file",sep=""),type="open",filter=list("text"=list(patterns=list("*.txt","*.csv","*.tab")),"all"=list(patterns=list("*"))))
if(length(proffile)==0) return()
Data = MPSproto::importMPSsample(proffile) #load profile (converts from table to list format)
#MUST UTILIZE LUSstrR if sequences are given
#converting to "CE:bracket" format
#Special handling
if(type=="ref") { #check that homozygote alleles are given twice
txt2 <- "The number of alleles in a genotype must be 2."
txt1 <- paste0("Only one allele was given for a genotype in a reference profile. ",txt2, " Hence the second allele was automatically set as the first allele.")
txt3 <- paste0("Too many alleles where given for a genotype in a reference profile. ",txt2)
miss <- FALSE #indicator whether hom. are missing
for(kn in names(Data)) { #for each profile
for(loc in names(Data[[kn]])) { #for each profile
if( length(Data[[kn]][[loc]]$adata)>2 ) {
gWidgets2::gmessage(txt3,"Wrong file-input",icon="error")
break #breaking loop if wrong input
}
if( length(Data[[kn]][[loc]]$adata)==1) {
Data[[kn]][[loc]]$adata <- rep(Data[[kn]][[loc]]$adata,2) #duplicated
miss <- TRUE
}
Data[[kn]][[loc]]$hdata = NULL #Updated v2.1.0: Remove peak heights if these have been added for references.
}
}
if(miss) gWidgets2::gmessage(txt1,"Warning",icon="info")
}
#get already stored data:
if(type=="mix") Data2 <- .getData("mix") #get data from mmTK-environment
if(type=="ref") Data2 <- .getData("ref") #get data from mmTK-environment
oldNames = names(Data2) #old samples
if(is.null(Data2)) { #if no previous already there
Data2 <- Data
} else {
for(kn in names(Data)) Data2[[kn]] <- Data[[kn]] #insert dataframe for each profile
}
if(type=="mix") assign("mixData",Data2,envir=mmTK) #assign data to mmTK-environment
if(type=="ref") assign("refData",Data2,envir=mmTK) #assign data to mmTK-environment
sampleNames = names(Data2) #Updated samplenames
#Update table
if(type=="mix") tabimportC[1,1][] <- cbind(sampleNames)
if(type=="ref") tabimportC[1,2][] <- cbind(sampleNames)
}
#Compare references against each evidence
.f_compare = function(h,...) {
evidD = .getData("mix") #get selected references
refD <- .getData("ref")
nEvids = length(evidD)
nRefs = length(refD)
if(nEvids==0 || nRefs==0) {
print("Missing data to compare...")
return()
}
nLocs <- MAC <- matrix(0,nrow=nEvids,nRefs,dimnames = list(names(evidD),names(refD)))
for(evid in names(evidD) ) { #for each selected evidence
subD <- evidD[[evid]] #selected samples
locs <- names(subD) #obtain locs
for(loc in locs) { #for each locus
evidA = subD[[loc]]$adata #allele vector of evid
if( length(evidA)==0) next #don't count missing markers
if( any( grepl(":",evidA) )) {
tmp = strsplit(evidA,":") #remove
evidA = sapply(tmp,function(x) x[2])
}
for(ref in names(refD) ) { #for each selected evidence
refA <- refD[[ref]][[loc]]$adata
if(is.null(refA) || length(refA)==0) next #skip if no data
nLocs[evid,ref] = nLocs[evid,ref] + 1 #count locus
MAC[evid,ref] <- MAC[evid,ref] + sum(refA%in%evidA) #count number of alleles
}
}
}
matchrate <- MAC/(2*nLocs)
nMissMatches = 2*nLocs - MAC
print("---NUMBER OF MISSMATCHES FOR EACH REFERENCES/SAMPLES:")
.printTable(nMissMatches)
}
#prints evidence, references, EPG, databases and population frequencies
.f_viewdata = function(h,...) {
sep = "--------------------------------------------"
help_gmessage = function(what) gWidgets2::gmessage(paste0("Please import and select ",what),icon="info")
#View evidence:
mixSel <- gWidgets2::svalue(tabimportC[1,1]) #get selected references
refSel <- gWidgets2::svalue(tabimportC[1,2]) #get selected references
evidD = .getData("mix",mixSel) #get selected references
refD <- .getData("ref",refSel)
nrefs = length(refD) #number of refs
#PRINT TO CONSOLE:
for(evidName in names(evidD) ) {
subD <- evidD[[evidName]] #selected samples
print("------------------------------------")
print(paste("Samplename: ",evidName,sep=""))
.printEvid(subD)
}
if(nrefs>0) .printRefs(refD,refSel)
#FINALLY: SHOW EPGs (but first, modify allles of referenes)
if(length(mixSel)>0) {
refD2=refD #modify alleles of refernces
if(nrefs>0) { #if any referenes
CEsep = ":"
locs = unique(unlist(lapply(refD,names))) #get loci to consider
for(loc in locs) {
#loc=locs[1]
alleles = unique( unlist(lapply(evidD,function(x) x[[loc]]$adata) ))
if( !any(grepl(CEsep,alleles)) ) next
convtab = matrix(unlist(strsplit(alleles,CEsep)),nrow=2) #convert table
for(ref in refSel) {
#ref = refSel[1]
av <- unlist(refD2[[ref]][[loc]])
found = av%in%convtab[2,]
ind = match(av[found],convtab[2,]) #get col inds
av[found] = paste0(convtab[1,ind],CEsep,av[found])
refD2[[ref]][[loc]]$adata = av #insert again
}
}
}
MPSproto::plotMPS(evidD,refD2)
}
} #end viewdata
.f_viewcalib = function(h,...) {
calibrated = get("calibrated",envir=mmTK) #assign calibrated object
locs = names(calibrated)
cns = unique(unlist(sapply(calibrated,names)))
tab = NULL
for(loc in locs) {
row = rep("",length(cns))
for(c in seq_along(cns)) {
elem = calibrated[[loc]][[cns[c]]] #extract
if(!is.null(elem)) row[c] = paste0(round(elem,3),collapse="/")
}
tab = rbind(tab,row)
}
rownames(tab) = locs
colnames(tab) = cns
print(tab)
dbwin <- gWidgets2::gwindow("Calibrated model", visible=FALSE)#,height=mwH)
gWidgets2::gtable( .addRownameTable(tab) ,container=dbwin) #create table
gWidgets2::visible(dbwin) <- TRUE
}
#helpfunction used to extract selected importdata-elements to further model-setup
.selectDataToModel <- function(h,....) {
#All: popFreq must be imported!
#EVID: must have both mixture and reference profiles
#DC: Deconvolution requires only mixtures. Reference profiles is optional
popFreq <- get("popFreq",envir=mmTK)
mixSel <- refSel <- numeric()
if(length(tabimportC[1,1][])>0) mixSel <- gWidgets2::svalue(tabimportC[1,1]) #get selected mixtures
if(length(tabimportC[1,2][])>0) refSel <- gWidgets2::svalue(tabimportC[1,2]) #get selected references
if(is.null(popFreq)) {
gWidgets2::gmessage("No frequencies was specified!\n Please import table with population frequencies.")
} else if(length(mixSel)==0) {
gWidgets2::gmessage("Please import and select evidence-profile!")
} else {
refreshTabModel(mixSel,refSel) #refresh table with selected data
gWidgets2::svalue(nb) <- 2 #change tab of notebook
}
} #end selectDataToModel
#Choose box and import button
.setAsImported = function(fn,widget) { #set as imported
gWidgets2::svalue(widget) <- "selected"
gWidgets2::font(widget) <- list(weight="bold",size=11,color="green")
.helptext(widget,fn) #set file name in .helptext
}
#helpfunction to store changed kit or platform type to environment and to file
.f_selectedKit = function(h,...) {
optKit = get("optKit", envir=mmTK) #obtain stored object
if(h$action=="platform") optKit$platform = gWidgets2::svalue(tabimportA[3,2])
if(h$action=="kit") optKit$kit = gWidgets2::svalue(tabimportA[4,2])
assign("optKit",optKit,envir=mmTK) #assign to environment
write(unlist(optKit),file=configList$optKit) #STORE TO SYSTEM FILE
}
###############
#start layout:#
###############
tabimport = gWidgets2::ggroup(container=tabimport0,horizontal = FALSE)
#tabimport2 = gWidgets2::ggroup(container=tabimport0)
tabimportA = gWidgets2::glayout(spacing=3,container=gWidgets2::gframe("Step 1) Import model data",container=tabimport)) #kit and population selecter
tabimportB = gWidgets2::glayout(spacing=3,container=gWidgets2::gframe("Step 2) Import Profiles",container=tabimport)) #kit and population selecter
tabimportC = gWidgets2::glayout(spacing=3,container=gWidgets2::gframe("Step 3) Select Evidence(s) and Reference(s)",container=tabimport,expand=T,fill=T),expand=T,fill=T) #evidence,ref dataframe
tabimportD = gWidgets2::glayout(spacing=3,container=gWidgets2::gframe("Step 4) Select Interpretation",container=tabimport)) #Tasks button
#SELECTION OF POPULATION FREQUENCIES
tabimportA[1,1] = gWidgets2::gbutton(text="Import frequencies",container=tabimportA,handler=
function(h,...) {
fn = .mygfile(text="Select file",type="open",filter = list(`All files` = list(patterns = c("*"))))
if(length(fn)==0) return()
popFreq = MPSproto::importMPSfreqs(fn)[[1]]
assign("popFreq",popFreq,envir=mmTK) #assign popFreq
assign("Freqfile",fn,envir=mmTK) #store filename
.setAsImported(fn,tabimportA[1,2] ) #set label as imported
write(fn,file= configList$optFreqFile ) #STORE TO SYSTEM FILE
})
.helptext(tabimportA[1,1],paste0("Choose a frequency file (LRmix/EFM format)."))
tabimportA[1,2] <- gWidgets2::glabel("none", container=tabimportA) #Create label of whether freq data is imported:
if(!is.null(get("popFreq",envir=mmTK))) .setAsImported( optList$optFreqFile, tabimportA[1,2] )
#SELECTION OF CALIBRATED OBJECT
tabimportA[2,1] = gWidgets2::gbutton(text="Import calibrated",container=tabimportA,handler=
function(h,...) {
fn = .mygfile(text="Select file",type="open",filter = list(`All files` = list(patterns = c("*"))))
if(length(fn)==0) return()
calibrated = .getCalibrated(fn)
assign("calibrated",calibrated,envir=mmTK) #assign calibrated object
assign("calibFile",fn,envir=mmTK) #store filename
.setAsImported(fn,tabimportA[2,2]) #set label as imported
write(fn,file= configList$optCalibFile ) #STORE TO SYSTEM FILE
})
.helptext(tabimportA[2,1],paste0("Choose a calibration file (Rds format)."))
tabimportA[2,2] <- gWidgets2::glabel("none", container=tabimportA) #Create label of whether calibration data is imported:
if(!is.null(get("calibrated",envir=mmTK))) .setAsImported( optList$optCalibFile, tabimportA[2,2] )
#ADDING VIEW BUTTONS
tabimportA[1,3] = gWidgets2::gbutton(text="View",container=tabimportA,handler=function(h,...) { print(get("popFreq",envir=mmTK)) })
tabimportA[2,3] = gWidgets2::gbutton(text="View",container=tabimportA,handler=.f_viewcalib)
#ADDING platform and kit selections
tabimportA[3,1] = gWidgets2::glabel("Platform",container=tabimportA)
selPlatform = get("optKit", envir=mmTK)$platform
tabimportA[3,2] = gWidgets2::gradio(c("MPS","CE"),select=selPlatform, container=tabimportA,horizontal = TRUE, handler=.f_selectedKit, action="platform")
tabimportA[4,1] = gWidgets2::glabel("Kit:",container=tabimportA)
listKits <- c("NONE",MPSproto::getMPSkit()) #list kit names (shortname)
selKit = which(listKits==get("optKit", envir=mmTK)$kit)
if(length(selKit)==0) selKit = 1 #first by default
tabimportA[4,2] = gWidgets2::gcombobox(items=listKits, width=100, selected = selKit , editable = FALSE , container = tabimportA, handler=.f_selectedKit, action="kit")
#Set other import buttons
tabimportB[1,1] = gWidgets2::gbutton(text="Import evidence",container=tabimportB,handler=.f_importprof,action="mix")
.helptext(tabimportB[1,1],"Imports evidence profile(s) from a selected file. \n\nThe column names must contain 'sample..', 'marker', 'allele..', 'height..'.")
tabimportB[1,2] = gWidgets2::gbutton(text="Import reference",container=tabimportB,handler=.f_importprof,action="ref")
.helptext(tabimportB[1,2],"Imports reference profile(s) from a selected file. \n\nThe column names must contain 'sample..', 'marker', 'allele..'.")
tabimportC[1,1] = gWidgets2::gcheckboxgroup(items= .getDataNames_type("mix"), container = tabimportC, use.table=TRUE)
tabimportC[1,2] = gWidgets2::gcheckboxgroup(items= .getDataNames_type("ref"), container = tabimportC, use.table=TRUE)
gWidgets2::size(tabimportC[1,1]) <- gWidgets2::size(tabimportC[1,2]) <- c(450,150) #c(600,150)
#Button-choices further (INTERPRETATION:
tabimportD[1,1] = gWidgets2::gbutton(text="View data",container=tabimportD,handler=.f_viewdata)
.helptext(tabimportD[1,1],"Print all selected data to console. Selected Evidence profiles are shown as EPGs (replicates for those in same group).")
tabimportD[1,2] = gWidgets2::gbutton(text="Compare data",container=tabimportD,handler=.f_compare)
.helptext(tabimportD[1,2],"Obtain number of missmatches between all references and evidences.")
tabimportD[1,3] = gWidgets2::gbutton(text="Interpretation",container=tabimportD,handler=.selectDataToModel)
.helptext(tabimportD[1,3],"A module for calculating the Likelihood Ratio or Deconvolution for selected sample(s) (treated as replicates).")
tabimportD[1,5] = gWidgets2::gbutton(text="RESTART",container=tabimportD,handler=function(h,...) {
gWidgets2::dispose(mainwin) #remove window!
MPSproto::gui() # open gui again
})
####################################################################################################################
#######################################Tab 2: Hypotheses:##########################################################
#####################################################################################################################
# mixSel= names(.getData("mix"));refSel=names(.getData("ref"));
refreshTabModel = function(mixSel,refSel) {
booltxt = c(TRUE,FALSE)
names(booltxt) = c("Yes","No")
nRefs = length(refSel)
nEvids = length(mixSel)
mixData2 = get("mixData",envir=mmTK)[mixSel]
refData2 = NULL
if(nRefs>0) refData2 = get("refData",envir=mmTK)[refSel]
#Obtain all alleles:
allAlleles <- unlist(lapply(mixData2,function(x) unlist(lapply(x,function(y) y$adata)))) #get allele names of sample
#helpfunction which takes GUI settings and stores them in "set'type'"
storeSettings = function() {
#EXTRACT HYPOTHESIS SPECIFICATION (tabmodelA1, tabmodelA2)
#get specified preposition
NOC = as.integer(gWidgets2::svalue(tabmodelA1[1,2])) #number of contributors is fixed!
.checkValue(NOC,"posInt","Number of contributors under Hp/Hd")
nC_hp <- nC_hd <- NOC #number of contributors in model:
condOrder_hp <- condOrder_hd <- rep(0,nRefs)
knownref_hp <- knownref_hd <- NULL #Typed profiles (known non-contributors)
for(row in seq_along(refSel)) { #traverse each reference
valhd <- as.integer(gWidgets2::svalue(tabmodelA2$hd[row,2])) #Hd
condOrder_hd[row] <- valhd + valhd*max(condOrder_hd)
valhp <- as.integer(gWidgets2::svalue(tabmodelA2$hp[row,2])) #Hp
condOrder_hp[row] <- valhp + valhp*max(condOrder_hp)
}
knownref_hp <- which(condOrder_hp==0) #those not conditioned on under Hp
if(length(knownref_hp)==0) knownref_hp <- NULL
#THIS IS DONE FOR BOTH DC AND EVID
knownref_hd <- which(condOrder_hd==0) #those not conditioned on under Hd
if(length(knownref_hd)==0) knownref_hd <- NULL
#get specified preposition
nHp = sum(condOrder_hp>0) #number of conditionals
nHd = sum(condOrder_hd>0) #number of conditionals
if( nHp > NOC || nHd > NOC) {
gWidgets2::gmessage("The number of contributors was speified too low!",title="Wrong setting",icon="error")
return(0) #return with error
}
if(nHp==0) nC_hp = NULL #SET TO NULL TO INDICATE THAT Hp is not to be calculated
#get input to list: note: "fit_hp" and "fit_hd" are list-object from fitted model
optFreq = get("optFreq",envir=mmTK)
fst = optFreq$fst #obtain selected fst
normalize = as.logical(optFreq$normalize)
freqsize = optFreq$freqsize
minF = optFreq$minF
if(!is.null(minF) && minF==0) minF = NULL
if(!is.null(freqsize) && freqsize>0) minF = 5/(2*freqsize) #rule 5/2n rule
hyp = list(hp = list(NOC=nC_hp,condOrder=condOrder_hp,knownRef=knownref_hp,fst=fst,normalize=normalize,minF=minF),
hd = list(NOC=nC_hd,condOrder=condOrder_hd,knownRef=knownref_hd,fst=fst,normalize=normalize,minF=minF))
#Extract selected model options
model = list(MOD=gWidgets2::svalue(tabmodelB[2,2]), #distribution
DEG=booltxt[[gWidgets2::svalue(tabmodelB[1,2])]], #degradation
EXT=booltxt[[2]]) #svalue(tabmodelB[3,2])]]) #Extra model fit?
#Store to a listed object
set <- list(samples=mixData2,refData=refData2,model=model,hyp=hyp)
calcList = get("calcList",envir=mmTK) #obtain already calculated objects
if(is.null(calcList)) calcList = list()
calcList[[length(calcList)+1]] = set #insert object
assign("calcList",calcList,envir=mmTK) #store data to envir
return(1) #success
} #end store settings from GUI to environment
#type={EVID",DC"}
gWidgets2::visible(mainwin) <- FALSE
# dispose(tabmodel)
tabmodeltmp <- gWidgets2::glayout(spacing=spc,container= tabmodel[1,1] <- gWidgets2::ggroup(container=tabmodel) )
#tabmodelCC = gWidgets2::glayout(spacing=10,container=(tabmodeltmp[1,1] <-gWidgets2::gframe(spacing=10,container=tabmodeltmp)))
tabmodelA = gWidgets2::glayout(spacing=5,container=(tabmodeltmp[1,1] <-gWidgets2::gframe("Hypothesis specification",container=tabmodeltmp)))
tabmodelB = gWidgets2::glayout(spacing=1,container=(tabmodeltmp[2,1] <-gWidgets2::gframe("Model specification",container=tabmodeltmp)))
tabmodelC = gWidgets2::glayout(spacing=1,container=(tabmodeltmp[3,1] <-gWidgets2::gframe("Further:",container=tabmodeltmp)))
#Obtain evid settings
edwith = 6 #edit width
NOCsel = nRefs + 1
#Hypothesis selection: subframe of A
Krange <- 1:maxKsetup #default Contr range
txt <- "Contributor(s) under H"
tabmodelA1 = gWidgets2::glayout(spacing=0,container=(tabmodelA[1,1] <-gWidgets2::gframe("Number of contributors",container=tabmodelA)))
tabmodelA1[1,1] <- gWidgets2::glabel("NOC:",container=tabmodelA1)
tabmodelA1[1,2] <- gWidgets2::gcombobox(items=Krange,selected=NOCsel,editable=TRUE,container=tabmodelA1)
gWidgets2::size(tabmodelA1[1,2]) = 3 #set with
# tabmodelTmp= tabmodelA2$hp
.createHypSetup = function(hypsel,checked=TRUE) { #Helpfunction
tabmodelTmp = tabmodelA2[[hypsel]]
for(rsel in refSel) { #indicate all selected references
rowind = which(rsel==refSel)
tabmodelTmp[rowind,1] <- gWidgets2::glabel(paste0("C",rowind),container=tabmodelTmp)
tabmodelTmp[rowind,2] <- gWidgets2::gcheckbox(rsel,container=tabmodelTmp,checked=checked)
}
}
tabmodelA2 = list()
tabmodelA2$hp = gWidgets2::glayout(spacing=0,container=(tabmodelA[2,1] <-gWidgets2::gframe(paste0(txt,"p:"),container=tabmodelA)))
.createHypSetup("hp",TRUE)
tabmodelA2$hd = gWidgets2::glayout(spacing=0,container=(tabmodelA[3,1] <-gWidgets2::gframe( paste0(txt,"d:"),container=tabmodelA)))
.createHypSetup("hd",TRUE)
#Model specification (replicates):
tabmodelB[1,1] <- gWidgets2::glabel(text="Degradation",container=tabmodelB)
tabmodelB[1,2] <- gWidgets2::gradio(names(booltxt),selected = 2,horizontal = TRUE,container=tabmodelB)
tabmodelB[2,1] <- gWidgets2::glabel(text="Model",container=tabmodelB)
tabmodelB[2,2] <- gWidgets2::gradio(c("GA","NB"),selected = 1,horizontal = TRUE,container=tabmodelB)
#tabmodelB[3,1] <- gWidgets2::glabel(text="Extended",container=tabmodelB)
#tabmodelB[3,2] <- gWidgets2::gradio(names(booltxt),selected = 2,horizontal = TRUE,container=tabmodelB)
#BLOCK FOR DEACTIVATING DEGRADATION OPTION
allowDEG = TRUE
optKit = get("optKit",envir=mmTK) #obtain kit info
if(is.null(optKit$kit) || optKit$kit=="NONE") allowDEG = FALSE #Turn off DEG option if kit not defined
if(allowDEG && any(!grepl(CEsep,allAlleles))) allowDEG = FALSE #Turn off DEG option if any alleles is missing CE
if(!allowDEG) gWidgets2::enabled(tabmodelB[1,2]) = FALSE #Turn off DEG option
#Calculation button:
tabmodelC[1,1] = gWidgets2::gbutton(text="CALCULATE",container=tabmodelC,handler=
function(h,...) {
ret = storeSettings() #store settings
if(ret==0) return() #don't continue if value is 0
doCalculate() #refresh MLE fit tab (i.e. it fits the specified model)
gWidgets2::svalue(nb) <- 3 #go to mle-fit window (for all cases) when finished
}) #end cont. calculation button
gWidgets2::visible(mainwin) <- TRUE
gWidgets2::focus(mainwin) <- TRUE
} #end refresh setup tab-frame
########################################################################################
############################ CALCULATION STEP ########################################
########################################################################################
#BEGIN MAIN FUNCTION (wrapper:
doCalculate = function(resID=NULL) { #resID is index to show (elemnent in calcList)
dec <- 4 #number of significant numbers to have in MLE print
gWidgets2::visible(mainwin) <- FALSE
calcList <- get("calcList",envir=mmTK) #obtain list with calculations:
nCalcs = length(calcList) #number of calculations done
if(is.null(resID)) resID = nCalcs #uselast element if not selected
set = calcList[[resID]] #use selected element
if(is.null(set)) return() #NO DATA ARE GIVEN (return...)
#PREPARE CALCULATIONS: DONE IF mlefit_hd is not obtained#
#take out relevant parameters from stored list
mod <- set$model #obtain param settings of model
hyp <- set$hyp #obtain hypotheses
par <- set$param #obtain parameters
calcHp = !is.null( hyp$hp$NOC) #whether Hp is considered (NOT NULL)
calcMLE = function(hyp) { #helpfunction for optimizing likelihood function (hypothesis setup is changed)
optMLE = get("optMLE",envir=mmTK) #Obtain optimizing options
optFreq = get("optFreq",envir=mmTK)
optKit = get("optKit",envir=mmTK)
popFreq = get("popFreq",envir=mmTK)
calibration = get("calibrated",envir=mmTK)
seed0 = optMLE$seed
if(seed0==0) seed0=NULL #convert seed to NULL (0 means none)
kit0 = optKit$kit
if(kit0=="NONE" || mod$DEG==FALSE) kit0 = NULL #Dont use degradation
#print(paste0(optMLE$nDone," random startpoints with variation ",optMLE$delta," are applied in the optimizer."))
MPSproto::inferEvidence(set$samples, popFreq, set$refData, hyp, calibration,
kit = kit0, optKit$platform, nDone = optMLE$nDone, delta = optMLE$delta,
steptol = optMLE$steptol, seed = seed0, verbose = FALSE, model = mod$MOD)
}
#fit under hp: (only for evidence)
mlefit_hp <- NULL #not used otherwise
if( calcHp ) { #considering HP
#nUhp <- mod$nC_hp-sum(mod$condOrder_hp>0) #number of unknowns
print("Calculating under Hp...")
time <- system.time({ mlefit_hp <- calcMLE(hy=hyp$hp) })[3]
print(paste0("Optimizing under Hp took ",format(time,digits=5),"s"))
if(!is.null(set$mlefit_hp) && set$mlefit_hp$fit$loglik>mlefit_hp$fit$loglik ) mlefit_hp <- set$mlefit_hp #the old model was better
}
#fit under hd: (does it for all methods)
print("Calculating under Hd...")
time <- system.time({ mlefit_hd <- calcMLE(hy=hyp$hd) })[3]
print(paste0("Optimizing under Hd took ",format(time,digits=5),"s"))
if(!is.null(set$mlefit_hd) && set$mlefit_hd$fit$loglik>mlefit_hd$fit$loglik ) mlefit_hd <- set$mlefit_hd #the old model was better
fixmsg <- "The specified model could not explain the data.\nPlease re-specify the model."
if(is.infinite(mlefit_hd$fit$loglik)) {
gWidgets2::gmessage(fixmsg,title="Wrong model specification (Hd)",icon="error")
} else if(calcHp && !is.infinite(set$mlefit_hd$fit$loglik) && is.infinite(mlefit_hp$fit$loglik)) {
gWidgets2::gmessage(fixmsg,title="Wrong model specification (Hp)",icon="error")
}
#store MLE result: also store best mle-values once again (possible with re-running optim)
set$mlefit_hp=mlefit_hp #store fitted mle-fit
set$mlefit_hd=mlefit_hd #store fitted mle-fit
#Store by-products of calculation:
set = .getMeta(set)
#Update calculated object to environment:
calcList[[resID]] = set #insert
assign("calcList",calcList,envir=mmTK) #obtain list with calculations:
refreshResults(resID)
} #ENDING CALCULATIONS
#helpfunction to get different "meta values" after calculations
.getMeta = function(set) {
#set = get("calcList",envir=mmTK)[[1]]
fithp = set$mlefit_hp
fithd = set$mlefit_hd
calcHp = !is.null(fithp) #check if calculated under hp
#Get log-lik values
loglikHp = fithp$fit$loglik
loglikHd = fithd$fit$loglik
loglikiHp = NULL
if(calcHp) loglikiHp = MPSproto::logLiki(fithp)
loglikiHd = MPSproto::logLiki(fithd)
#Obtain LR-values:
set$log10LR <- (loglikHp - loglikHd)/log(10) #obtain LR (log10)
set$log10LRtxt = ""
if(length(set$log10LR)>0) set$log10LRtxt <- round(set$log10LR,2)
set$upperLR <- MPSproto::getUpperLR(fithd,scale=TRUE) #obtain upper LR
set$upperLRtxt = ""
if(length(set$upperLR)>0 && set$upperLR!="") set$upperLRtxt = round(set$upperLR,2) #needs to be a numeric!
set$log10LRi = (loglikiHp - loglikiHd)/log(10)
#Get params
thetaHp = fithp$fit$par
thetaHd = fithd$fit$par
nparHp = length(fithp$fit$phihat) #number of unknown params
nparHd = length(fithd$fit$phihat) #number of unknown params
#get adjusted loglik ("aic" alike): penalize with number of (effective) parameters
set$adjLL_hp <- loglikHp - nparHp
set$adjLL_hd <- loglikHd - nparHd
#Obtain text
evidNames = names(set$samples) #extract reference names
refNames = names(set$refData) #extract reference names
condHp <- set$hyp$hp$condOrder
condHd <- set$hyp$hd$condOrder
iscondHp <- which(condHp>0)
iscondHd <- which(condHd>0)
POIind = setdiff(iscondHp,iscondHd) #get contribution indices under Hp but not hd
CONDind = intersect(iscondHp,iscondHd) #get contribution indices under both Hp and Hd
#INSERT
set$evidNames = paste0(evidNames,collapse="/")
set$POI = paste0(refNames[POIind],collapse="/")
set$COND = paste0(refNames[CONDind],collapse="/")
set$NOC = length(thetaHd$mx) #number of contributors
set$POI_mx = thetaHp$mx[POIind] #get Mx of POI (under hp)
set$POImxtxt = ""
if(length(set$POI_mx)>0) set$POImxtxt = paste0(signif(set$POI_mx*100,2),"%")
set$COND_mx = thetaHp$mx[CONDind] #get Mx of COND (under hp)
set$MOD = set$model$MOD
set$DEG = ifelse(set$model$DEG,"Yes","No")
set$EXT = ifelse(set$model$EXT,"Yes","No")
#set$model #other info already inside
#obtain hyp text:
nUhp = set$NOC - length(iscondHp)
nUhd = set$NOC - length(iscondHd)
#Naming Components of Mx estimates:
set$MxRefsHp = thetaHp$mx
set$MxRefsHd = thetaHd$mx
names(set$MxRefsHp)[condHp] = refNames[iscondHp]
names(set$MxRefsHd)[condHd] = refNames[iscondHd]
if(nUhp>0) names(set$MxRefsHp)[which(is.na(names(set$MxRefsHp)))] = paste0("Unknown ",1:nUhp)
if(nUhd>0) names(set$MxRefsHd)[which(is.na(names(set$MxRefsHd)))] = paste0("Unknown ",1:nUhd)
getHypTxt = function(ref,nU) {
txt=""
if(length(ref)>0) txt = paste0(txt, paste0(ref,collapse="/"))
if(nU>0) {
tmp = paste0(nU," unknown")
if(nU>1) tmp = paste0(tmp,"s") #plural
if(length(ref)>0) tmp = paste0(" + ",tmp) #additional to refs
txt = paste0(txt, tmp)
}
return(txt)
}
set$hypTxt = c(NA,getHypTxt(refNames[iscondHd],nUhd)) #create hyp-text
if( calcHp ) set$hypTxt[1] = getHypTxt(refNames[iscondHp],nUhp)
names(set$hypTxt) = paste0("H",c("p","d"),": ",set$hypTxt) #insert
return(set) #return updated object
} #end get meta
########################################################################################
############################Tab 3: RESULT TABLE:########################################
########################################################################################
#This section involved calculations and obtaining different results
#Helpfunction to show table in GDF (editable cells)
.showGDFtable = function(title,table) {
setwin2 <- gWidgets2::gwindow( title ,visible=FALSE)
guitab <- gWidgets2::gdf(items=table,container = setwin2)
gWidgets2::visible(setwin2) <- TRUE
gWidgets2::focus(setwin2) <- TRUE
}
#helpfunction ran when call deconvolution
.doDC <- function(mleobj) {
dcopt <- get("optDC",envir=mmTK) #options when Deconvolution
dcobj <- MPSproto::deconvolve(mlefit=mleobj,alpha=dcopt$alphaprob,maxlist=dcopt$maxlist)
DCtable1 <- .addRownameTable(dcobj$table2)
colnames(DCtable1)[1] <- "Locus"
DCtable2<-dcobj$table1
DCtable3<-dcobj$table3
DCtable4<-dcobj$table4
assign("resDC",list(DCtable1,DCtable2,DCtable3,DCtable4),envir=mmTK) #assign deconvolved result to environment
.refreshTabDC() #update table with deconvolved results
gWidgets2::svalue(nb) <- 4 #go to deconvolution results window (for all cases) when finished
gWidgets2::focus(mainwin) <- TRUE
}
.f_showPerMarkerLR = function(h,...) {
LRi = h$action
print("------------LR-perMarker-----------------")
tab = cbind(LRi,log10(LRi))
colnames(tab) = c("LR","log10LR")
print(tab)
}
#helpfunction to get ID-element of tabMLEresGUI/calcList
.getID = function() {
sel = gWidgets2::svalue(tabMLEresGUI) #get selected row
if(is.null(sel)) return(0) #ID=0 means none
return(as.integer(gsub("#","",sel)))
}
#Helpf
.f_exporttable = function(h,...) {
resTable = tabMLEresGUI[]
if(is.null(resTable)) return()
.saveTable(resTable) #save table
}
.f_createreport = function(h,...) {
print("NOT IMPLEMENTED")
}
#helpfunction to calculate extended
.f_calcext = function(h,...) {
print("NOT IMPLEMENTED")
}
#helpfunction to get different options (a new window)
.f_getoptions = function(h,...) {
id = .getID()
if(id==0) return()
calcRes <- get("calcList",envir=mmTK)[[id]] #obtain table
optwin <- gWidgets2::gwindow(paste0("More options for Hyp. set #",id) ,visible=FALSE)
optgrp = gWidgets2::ggroup(horizontal = FALSE,spacing=5,container=optwin)
opthead = gWidgets2::glayout(horizontal = FALSE,spacing=5,container=optgrp) #header with text
opthead[1,1] = gWidgets2::glabel("Sample(s):",container=opthead)
opthead[1,2] = gWidgets2::glabel(calcRes$evidNames,container=opthead)
opthead[2,1] = gWidgets2::glabel("Hp:",container=opthead)
opthead[2,2] = gWidgets2::glabel(calcRes$hypTxt[1],container=opthead)
opthead[3,1] = gWidgets2::glabel("Hd:",container=opthead)
opthead[3,2] = gWidgets2::glabel(calcRes$hypTxt[2],container=opthead)
opthead[4,1] = gWidgets2::glabel("Upper log10LR:",container=opthead)
opthead[4,2] = gWidgets2::glabel(calcRes$upperLRtxt,container=opthead)
optgrid = gWidgets2::glayout(horizontal = FALSE,spacing=5,container=optgrp)
optgrid[1,1] <- gWidgets2::gbutton("Show LR-per marker",container=optgrid,handler=function(h,...) {
s0 = 2
LRi = calcRes$log10LRi
tab <- cbind(round(LRi,s0), signif(10^(LRi),s0+1)) #obtain LR per marker
colnames(tab) = c("log10LR","LR")
print(tab) #print to console
.showGDFtable("LR per marker", .addRownameTable(tab,"Marker"))
barplot(LRi,xlab="",ylab="log10 LR",main="",las=2) #also show barplot
})
optgrid[2,1] <- gWidgets2::gbutton("Show estimated params.",container=optgrid,handler=function(h,...) {
hypsettxt = paste0(names(calcRes$hypTxt),collapse="/")
#Create param table
parHp = calcRes$mlefit_hp$fit$par
parHd = calcRes$mlefit_hd$fit$par
MxHp = parHp$mx
MxHd = parHd$mx
tab = round(cbind(unlist(parHp),unlist(parHd)),3)
colnames(tab) = c("Hp","Hd")
#add loglik values to table (last row):
logLikHp = calcRes$mlefit_hp$fit$loglik
logLikHd = calcRes$mlefit_hd$fit$loglik
tab = rbind(tab, logLik=round(c(logLikHp,logLikHd),3)) #add to last row
.showGDFtable(hypsettxt,.addRownameTable(tab,colname = "Param"))
print(tab) #to console
#Show mixture proportions in a separe plot:
if(require(plotrix)) {
MxHp2 = sort(calcRes$MxRefsHp,decreasing = TRUE) #sort to make same colors
MxHd2 = sort(calcRes$MxRefsHd,decreasing = TRUE) #sort to make same colors
s0 = 2
labelHp = paste0(names(MxHp2)," ",round(MxHp2*100),"%") #Obtain labels
labelHd = paste0(names(MxHd2)," ",round(MxHd2*100),"%") #Obtain labels
plotfn = paste0("WOEpie",id) #file name
graphics.off() #remove other plots first
png(plotfn,height=400,width=1000)
par(mfrow=c(1,2))
marg = c(0,5,0,6)
plotrix::pie3D(MxHp,radius=0.9,labels=labelHp,explode=0.1,main="Hp",mar=marg)
plotrix::pie3D(MxHd,radius=0.9,labels=labelHd,explode=0.1,main="Hd",mar=marg)
mtext(calcRes$evidNames,cex=1.5,outer=T,line=-2)
dev.off()
TopWin <- gWidgets2::gwindow(paste0("Mixture proportions for ",hypsettxt))#,width=800,height=400)
gWidgets2::gimage(plotfn,container=TopWin)
gWidgets2::focus(TopWin) = TRUE
file.remove(plotfn) #remove file after
}
})
optgrid[3,1] <- gWidgets2::gbutton("Show model validation",container=optgrid,handler=function(h,...) {
alpha0 = 0.01
hypsettxt = paste0("Hyp. set #",id)
#hyp = gWidgets2::gconfirm("Select hypothesis (Yes=Hp, No=Hd)","Choose hypothesis",icon = "question")
plotfn1 = paste0("WOEvalidHp",id) #file name
plotfn2 = paste0("WOEvalidHd",id) #file name
graphics.off() #remove other plots first
size0 = 600
png(plotfn1,height=size0,width=size0)
MPSproto::validMLE(calcRes$mlefit_hp,"Hp",alpha=alpha0,createplot = TRUE, verbose = TRUE)
dev.off()
png(plotfn2,height=size0,width=size0)
MPSproto::validMLE(calcRes$mlefit_hd,"Hd",alpha=alpha0,createplot = TRUE, verbose = TRUE)
dev.off()
TopWin <- gWidgets2::gwindow(paste0("Model validation for ",hypsettxt))#,width=800,height=400)
ggrp <- gWidgets2::ggroup(container=TopWin)
gWidgets2::gimage(plotfn1,container=ggrp)
gWidgets2::gimage(plotfn2,container=ggrp)
gWidgets2::focus(TopWin) = TRUE
file.remove(plotfn1) #remove file after
file.remove(plotfn2) #remove file after
})
optgrid[4,1] <- gWidgets2::gbutton("Show model fit",container=optgrid,handler=function(h,...) {
hyp = gWidgets2::gconfirm("Select hypothesis (Yes=Hp, No=Hd)","Choose hypothesis",icon = "question")
if(hyp) {
MPSproto::plotTopMPS( calcRes$mlefit_hp )
} else {
MPSproto::plotTopMPS( calcRes$mlefit_hd )
}
})
optgrid[5,1] <- gWidgets2::gbutton("Deconvolve",container=optgrid,handler=function(h,...) {
hyp = gWidgets2::gconfirm("Select hypothesis (Yes=Hp, No=Hd)","Choose hypothesis",icon = "question")
if(hyp) {
resDC = MPSproto::deconvolve( calcRes$mlefit_hp )
} else {
resDC = MPSproto::deconvolve( calcRes$mlefit_hd )
}
print("Deconvolve finished")
assign("resDC",resDC,envir=mmTK) #get deconvolved results
.refreshTabDC()
gWidgets2::svalue(nb) <- 4 #go to DC result tab when done
.getFocus()
})
gWidgets2::visible(optwin) <- TRUE
} #END OPTION WINDOW
#BEGIN GUI HERE:
tabMLEgrid = gWidgets2::glayout(horizontal = FALSE,spacing=5,container=tabMLE) #kit and population selecter
tabMLEgrid[1,1] <- gWidgets2::gbutton(text="Export table",container=tabMLEgrid,handler=.f_exporttable)#
tabMLEgrid[1,2] <- gWidgets2::gbutton(text="Create report",container=tabMLEgrid,handler=.f_createreport)#
tabMLEgrid[1,3] <- gWidgets2::gbutton(text="Infer LSAE (EXT)",container=tabMLEgrid,handler=.f_calcext)#
tabMLEgrid[1,4] <- gWidgets2::gbutton(text="More options",container=tabMLEgrid,handler=.f_getoptions)#
#This panel is for selecting different calculated results and showing comparison of calculated models
tabMLEres <- gWidgets2::ggroup(container=tabMLE,expand=TRUE,fill=TRUE)
tabMLEresGUI <- gWidgets2::gtable(items="",multiple = FALSE,container=tabMLEres, handler=.f_getoptions)
gWidgets2::add(tabMLEres,tabMLEresGUI,expand=TRUE,fill=TRUE)#add to frame
refreshResults = function(selrow=NULL) { #update result table
calcList <- get("calcList",envir=mmTK) #obtain table
nres = length(calcList) #number of results
if(nres==0) return() #no results
#Curate table:
cns = c("Sample(s)","PoI","Cond","NOC","MOD","DEG","EXT","LR","Mx","adj.logLik")
#x = calcList[[1]]
getRoundedAdjLL = function(val) ifelse(is.null(val),"", round(val,2)) #helpfunction to avoid crash
resTable = t(sapply(calcList,function(x) c(x$evidNames,x$POI,x$COND,x$NOC,x$MOD,x$DEG,x$EXT,x$log10LRtxt, x$POImxtxt ,getRoundedAdjLL(x$adjLL_hd))))
colnames(resTable) = cns
resTable = cbind(ID=paste0("#",1:nres),resTable)
tabMLEresGUI[] <- resTable
gWidgets2::size(tabMLEresGUI) <- list(column.widths=c(30,250,100,220,40,40,40,40,60,60,80))
if(!is.null(selrow)) gWidgets2::svalue(tabMLEresGUI) <- selrow #highlight row
.getFocus()
}
refreshResults() #Show already calculted evidence-results when program starts
##############################################################
###############Tab 5: Deconvolution results:##################
##############################################################
.f_savetableDC = function(h,...) {
if(is.null(DCtable)) {
gWidgets2::gmessage("There is no deconvolution results available!")
} else {
.saveTable(DCtable[], "txt") #save deconvolution results
}
}
.refreshTabDC = function(dctype=1) { #1=table1 (top marginal results),2=table2 (joint results), 3=table3 (all marginal results per genotype), 4=table4 (all marginal results per alleles)
DCtables <- get("resDC",envir=mmTK) #get deconvolved results
if(!is.null(DCtables)) {
DCtable[] = .NAtoSign(DCtables[[dctype]]) #update Table
}
}
#CREATE DECONV-GUI
tabDCa = gWidgets2::glayout(spacing=1,container=tabDC) #table layout
tabDCb = gWidgets2::ggroup(spacing=1,container=tabDC,expand=T,fill=T)
itemvecDC = c("Top Marginal","All Joint","All Marginal (G)","All Marginal (A)")
tabDCa[1,1] <- gWidgets2::glabel("Select layout:",container=tabDCa)
tabDCa[1,2] <- gWidgets2::gradio(items=itemvecDC,selected=1,horizontal=TRUE,container=tabDCa,handler=function(x) {
.refreshTabDC( which(itemvecDC==gWidgets2::svalue(tabDCa[1,2])) )
})
tabDCa[2,1] <- gWidgets2::gbutton(text="Save table",container=tabDCa,handler=.f_savetableDC)
#ADD DC TABLE
DCtable = gWidgets2::gtable(items="",multiple = TRUE,container = tabDCb,expand=T,fill=T)
gWidgets2::add(tabDCb,DCtable,expand=T,fill=T)
.refreshTabDC() #open results when program starts
for(nbvisit in 4:1) gWidgets2::svalue(nb) <- nbvisit #visit tables
.getFocus()
} #end funcions
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.