diff options
Diffstat (limited to 'inst')
-rw-r--r-- | inst/GUI/mkinGUI.R | 445 |
1 files changed, 445 insertions, 0 deletions
diff --git a/inst/GUI/mkinGUI.R b/inst/GUI/mkinGUI.R new file mode 100644 index 0000000..cf66b01 --- /dev/null +++ b/inst/GUI/mkinGUI.R @@ -0,0 +1,445 @@ +# $Id: mkinGUI.R 122 2013-10-21 20:19:57Z jranke $ {{{1
+
+# gWidgetsWWW2 GUI for mkin
+
+# Copyright (C) 2013 Johannes Ranke
+# Contact: jranke@uni-bremen.de, johannesranke@eurofins.com
+
+# This file is part of the R package mkin
+
+# mkin is free software: you can redistribute it and/or modify it under the
+# terms of the GNU General Public License as published by the Free Software
+# Foundation, either version 3 of the License, or (at your option) any later
+# version.
+
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+
+# You should have received a copy of the GNU General Public License along with
+# this program. If not, see <http://www.gnu.org/licenses/>
+require(mkin) # {{{1
+# Set the GUI title and create the basic widget layout {{{1
+w <- gwindow("Browser based GUI for kinetic evaluations using mkin")
+sb <- gstatusbar("Powered by gWidgetsWWW2 and Rook", cont = w)
+pg <- gpanedgroup(cont = w, default.size = 400)
+center <- gnotebook(cont = pg)
+left <- gvbox(cont = pg)
+# Helper functions {{{1
+# Override function for making it possible to override original data in the GUI {{{2
+override <- function(d) {
+ data.frame(name = d$name, time = d$time,
+ value = ifelse(is.na(d$override), d$value, d$override),
+ err = d$err)
+}
+# Set default values for project data {{{1
+# Initial project file name {{{2
+project_file <- "mkin_FOCUS_2006.RData"
+# Initial studies {{{2
+studies.df <- data.frame(Index = as.integer(1),
+ Author = "FOCUS kinetics workgroup",
+ Year = "2006",
+ Title = "FOCUS Kinetics",
+ stringsAsFactors = FALSE)
+# Initial datasets {{{2
+ds <- list()
+observed.all <- vector()
+for (i in 1:2) {
+ ds.letter = LETTERS[i + 2]
+ ds.index <- as.character(i)
+ ds.name = paste0("FOCUS_2006_", ds.letter)
+ ds[[ds.index]] <- list(
+ study_nr = 1,
+ title = paste("FOCUS example dataset", ds.letter),
+ sampling_times = unique(get(ds.name)$time),
+ time_unit = "",
+ observed = as.character(unique(get(ds.name)$name)),
+ unit = "% AR",
+ replicates = 1,
+ data = get(ds.name)
+ )
+ ds[[ds.index]]$data$name <- as.character(ds[[ds.index]]$data$name)
+ ds[[ds.index]]$data$override = as.numeric(NA)
+ ds[[ds.index]]$data$err = 1
+}
+# Dataframe with datasets for selection {{{2
+update_ds.df <- function() {
+ ds.n <- length(ds)
+ ds.df <<- data.frame(Index = 1:ds.n,
+ Title = character(ds.n),
+ Study = character(ds.n),
+ stringsAsFactors = FALSE)
+ for (i in 1:ds.n)
+ {
+ ds.index <- names(ds)[[i]]
+ ds.df[i, "Title"] <<- ds[[ds.index]]$title
+ ds.df[i, "Study"] <<- ds[[ds.index]]$study_nr
+ observed = as.character(unique(ds[[ds.index]]$data$name))
+ observed.all <<- union(observed, observed.all)
+ }
+}
+ds.df <- data.frame()
+update_ds.df()
+ds.cur = "1"
+# Initial models {{{2
+m <- list()
+m[["1"]] <- mkinmod(parent = list(type = "SFO"))
+m[["1"]]$name = "SFO"
+m[["2"]] <- mkinmod(parent = list(type = "FOMC"))
+m[["2"]]$name = "FOMC"
+m[["3"]] <- mkinmod(parent = list(type = "DFOP"))
+m[["3"]]$name = "DFOP"
+m[["4"]] <- mkinmod(parent = list(type = "SFO", to = "m1"),
+ m1 = list(type = "SFO"),
+ use_of_ff = "max")
+m[["4"]]$name = "SFO_SFO"
+# Dataframe with models for selection {{{2
+update_m.df <- function() {
+ m.n <- length(m)
+ m.df <<- data.frame(Index = 1:m.n,
+ Name = character(m.n),
+ stringsAsFactors = FALSE)
+ for (i in 1:m.n) {
+ m.index <- names(m)[[i]]
+ m.df[i, "Name"] <<- m[[m.index]]$name
+ }
+}
+m.df <- data.frame()
+update_m.df()
+m.cur = "1"
+# Widgets and handlers for project data {{{1
+prg <- gexpandgroup("Project file management", cont = left, horizontal = FALSE)
+visible(prg) <- FALSE
+# Project data management handler functions {{{2
+upload_file_handler <- function(h, ...)
+{
+ tmpfile <- normalizePath(svalue(h$obj), winslash = "/")
+ try(load(tmpfile))
+ project_file <<- pr.gf$filename
+ svalue(pr.ge) <- project_file
+ studies.gdf[,] <- studies.df
+ ds.cur <<- "1"
+ ds <<- ds
+ update_ds.df()
+ ds.gtable[,] <- ds.df
+ update_ds_editor()
+ m.cur <<- "1"
+ m <<- m
+ update_m.df()
+ m.gtable[,] <- m.df
+ update_m_editor()
+}
+save_to_file_handler <- function(h, ...)
+{
+ studies.df <- data.frame(studies.gdf[,], stringsAsFactors = FALSE)
+ save(studies.df, ds, m, file = project_file)
+ galert(paste("Saved project contents to", project_file), parent = w)
+}
+change_project_file_handler = function(h, ...) {
+ project_file <<- as.character(svalue(h$obj))
+}
+# Project data management GUI elements {{{2
+pr.gf <- gfile(text = "Select project file", cont = prg,
+ handler = upload_file_handler)
+pr.ge <- gedit(project_file, cont = prg,
+ handler = change_project_file_handler)
+# The save button is always visible {{{1
+gbutton("Save current project contents", cont = left,
+ handler = save_to_file_handler)
+
+# GUI widgets and a function for Studies {{{1
+stg <- gexpandgroup("Studies", cont = left)
+visible(stg) <- FALSE
+update_study_selector <- function(h, ...) {
+ delete(ds.e.1, ds.study.gc)
+ ds.study.gc <<- gcombobox(paste("Study", studies.gdf[,1]), cont = ds.e.1)
+ svalue(ds.study.gc, index = TRUE) <- ds[[ds.cur]]$study_nr
+}
+studies.gdf <- gdf(studies.df, name = "Edit studies in the project",
+ width = 390, height = 200, cont = stg)
+studies.gdf$set_column_width(1, 35)
+studies.gdf$set_column_width(2, 150)
+studies.gdf$set_column_width(3, 40)
+addHandlerChanged(studies.gdf, update_study_selector)
+# Datasets and models {{{1
+dsm <- gframe("Datasets and models", cont = left, horizontal = FALSE)
+# Dataset table with handler {{{2
+ds.switcher <- function(h, ...) {
+ ds.cur <<- as.character(svalue(h$obj))
+ update_ds_editor()
+ svalue(center) <- 1
+}
+ds.gtable <- gtable(ds.df, width = 390, multiple = TRUE, cont = dsm)
+addHandlerDoubleClick(ds.gtable, ds.switcher)
+size(ds.gtable) <- list(columnWidths = c(40, 300, 40))
+
+# Model table with handler {{{2
+m.switcher <- function(h, ...) {
+ m.cur <<- as.character(svalue(h$obj))
+ update_m_editor()
+ svalue(center) <- 2
+}
+m.gtable <- gtable(m.df, width = 390, multiple = TRUE, cont = dsm)
+addHandlerDoubleClick(m.gtable, m.switcher)
+size(m.gtable) <- list(columnWidths = c(40, 340))
+
+# Dataset editor {{{1
+ds.editor <- gframe("Dataset 1", horizontal = FALSE, cont = center, label = "Dataset editor")
+# Handler functions {{{3
+copy_dataset_handler <- function(h, ...) {
+ ds.old <- ds.cur
+ ds.cur <<- as.character(1 + length(ds))
+ svalue(ds.editor) <- paste("Dataset", ds.cur)
+ ds[[ds.cur]] <<- ds[[ds.old]]
+ update_ds.df()
+ ds.gtable[,] <- ds.df
+}
+
+delete_dataset_handler <- function(h, ...) {
+ ds[[ds.cur]] <<- NULL
+ names(ds) <<- names(plots) <<- names(prows) <<- as.character(1:length(ds))
+ ds.cur <<- names(ds)[[1]]
+ update_ds.df()
+ ds.gtable[,] <- ds.df
+ update_ds_editor()
+}
+
+new_dataset_handler <- function(h, ...) {
+ ds.cur <<- as.character(1 + length(ds))
+ ds[[ds.cur]] <<- list(
+ study_nr = 1,
+ title = "",
+ sampling_times = c(0, 1),
+ time_unit = "NA",
+ observed = "parent",
+ unit = "NA",
+ replicates = 1,
+ data = data.frame(
+ name = "parent",
+ time = c(0, 1),
+ value = c(100, NA),
+ override = "NA",
+ err = 1,
+ stringsAsFactors = FALSE
+ )
+ )
+ update_ds.df()
+ ds.gtable[,] <- ds.df
+ update_ds_editor()
+}
+
+empty_grid_handler <- function(h, ...) {
+ obs <- strsplit(svalue(ds.e.obs), ", ")[[1]]
+ sampling_times <- strsplit(svalue(ds.e.st), ", ")[[1]]
+ replicates <- as.numeric(svalue(ds.e.rep))
+ new.data = data.frame(
+ name = rep(obs, each = replicates * length(sampling_times)),
+ time = rep(sampling_times, each = replicates, times = length(obs)),
+ value = NA,
+ override = NA,
+ err = 1
+ )
+ ds.e.gdf[,] <- new.data
+}
+
+save_ds_changes_handler <- function(h, ...) {
+ ds[[ds.cur]]$title <<- svalue(ds.title.ge)
+ ds[[ds.cur]]$study_nr <<- as.numeric(gsub("Study ", "", svalue(ds.study.gc)))
+ update_ds.df()
+ ds.gtable[,] <- ds.df
+ tmpd <- ds.e.gdf[,]
+ ds[[ds.cur]]$data <<- tmpd
+ ds[[ds.cur]]$sampling_times <<- sort(unique(tmpd$time))
+ ds[[ds.cur]]$time_unit <<- svalue(ds.e.stu)
+ ds[[ds.cur]]$observed <<- unique(tmpd$name)
+ ds[[ds.cur]]$unit <<- svalue(ds.e.obu)
+ ds[[ds.cur]]$replicates <<- max(aggregate(tmpd$time,
+ list(tmpd$time, tmpd$name), length)$x)
+ update_ds_editor()
+ update_plot()
+}
+
+# Widget setup {{{3
+# Line 1 {{{4
+ds.e.1 <- ggroup(cont = ds.editor, horizontal = TRUE)
+glabel("Title: ", cont = ds.e.1)
+ds.title.ge <- gedit(ds[[ds.cur]]$title, cont = ds.e.1)
+glabel(" from ", cont = ds.e.1)
+ds.study.gc <- gcombobox(paste("Study", studies.gdf[,1]), cont = ds.e.1)
+
+# Line 2 {{{4
+ds.e.2 <- ggroup(cont = ds.editor, horizontal = TRUE)
+gbutton("Copy dataset", cont = ds.e.2, handler = copy_dataset_handler)
+gbutton("Delete dataset", cont = ds.e.2, handler = delete_dataset_handler)
+gbutton("New dataset", cont = ds.e.2, handler = new_dataset_handler)
+
+# Line 3 with forms {{{4
+ds.e.forms <- ggroup(cont= ds.editor, horizontal = TRUE)
+
+ds.e.3a <- gvbox(cont = ds.e.forms)
+ds.e.3a.gfl <- gformlayout(cont = ds.e.3a)
+ds.e.st <- gedit(paste(ds[[ds.cur]]$sampling_times, collapse = ", "),
+ width = 40,
+ label = "Sampling times",
+ cont = ds.e.3a.gfl)
+ds.e.stu <- gedit(ds[[ds.cur]]$time_unit,
+ width = 20,
+ label = "Unit", cont = ds.e.3a.gfl)
+ds.e.rep <- gedit(ds[[ds.cur]]$replicates,
+ width = 20,
+ label = "Replicates", cont = ds.e.3a.gfl)
+
+ds.e.3b <- gvbox(cont = ds.e.forms)
+ds.e.3b.gfl <- gformlayout(cont = ds.e.3b)
+ds.e.obs <- gedit(paste(ds[[ds.cur]]$observed, collapse = ", "),
+ width = 50,
+ label = "Observed", cont = ds.e.3b.gfl)
+ds.e.obu <- gedit(ds[[ds.cur]]$unit,
+ width = 20, label = "Unit",
+ cont = ds.e.3b.gfl)
+gbutton("Generate empty grid for kinetic data", cont = ds.e.3b,
+ handler = empty_grid_handler)
+
+# Save button {{{4
+gbutton("Save changes", cont = ds.editor, handler = save_ds_changes_handler)
+
+# Kinetic Data {{{4
+ds.e.gdf <- gdf(ds[[ds.cur]]$data, name = "Kinetic data",
+ width = 500, height = 700, cont = ds.editor)
+ds.e.gdf$set_column_width(2, 70)
+
+# Update the dataset editor {{{3
+update_ds_editor <- function() {
+ svalue(ds.editor) <- paste("Dataset", ds.cur)
+ svalue(ds.title.ge) <- ds[[ds.cur]]$title
+ svalue(ds.study.gc, index = TRUE) <- ds[[ds.cur]]$study_nr
+
+ svalue(ds.e.st) <- paste(ds[[ds.cur]]$sampling_times, collapse = ", ")
+ svalue(ds.e.stu) <- ds[[ds.cur]]$time_unit
+ svalue(ds.e.obs) <- paste(ds[[ds.cur]]$observed, collapse = ", ")
+ svalue(ds.e.obu) <- ds[[ds.cur]]$unit
+ svalue(ds.e.rep) <- ds[[ds.cur]]$replicates
+
+ ds.e.gdf[,] <- ds[[ds.cur]]$data
+}
+# Model editor {{{1
+m.editor <- gframe("Model 1", horizontal = FALSE, cont = center, label = "Model editor")
+# Handler functions {{{3
+copy_model_handler <- function(h, ...) {
+ m.old <- m.cur
+ m.cur <<- as.character(1 + length(m))
+ svalue(m.editor) <- paste("Model", m.cur)
+ m[[m.cur]] <<- m[[m.old]]
+ update_m.df()
+ m.gtable[,] <- m.df
+}
+
+delete_model_handler <- function(h, ...) {
+ m[[m.cur]] <<- NULL
+ names(m) <<- as.character(1:length(m))
+ m.cur <<- "1"
+ update_m.df()
+ m.gtable[,] <- m.df
+ update_m_editor()
+}
+
+add_observed_handler <- function(h, ...) {
+ obs.i <- length(m.e.rows) + 1
+ m.e.rows[[obs.i]] <<- ggroup(cont = m.editor, horizontal = TRUE)
+ m.e.obs[[obs.i]] <<- gcombobox(observed.all, selected = obs.i,
+ cont = m.e.rows[[obs.i]])
+ m.e.type[[obs.i]] <<- gcombobox(c("SFO", "FOMC", "DFOP", "HS", "SFORB"),
+ cont = m.e.rows[[obs.i]])
+ svalue(m.e.type[[obs.i]]) <- "SFO"
+ glabel("to", cont = m.e.rows[[obs.i]])
+ m.e.to[[obs.i]] <<- gedit("", cont = m.e.rows[[obs.i]])
+ m.e.sink[[obs.i]] <<- gcheckbox("Path to sink",
+ checked = TRUE, cont = m.e.rows[[obs.i]])
+ gbutton("Remove compound", handler = remove_compound_handler,
+ action = obs.i, cont = m.e.rows[[obs.i]])
+}
+
+remove_compound_handler <- function(h, ...) {
+ m[[m.cur]]$spec[[h$action]] <<- NULL
+ update_m_editor()
+}
+
+save_m_changes_handler <- function(h, ...) {
+ spec <- list()
+ for (obs.i in 1:length(m.e.rows)) {
+ spec[[obs.i]] <- list(type = svalue(m.e.type[[obs.i]]),
+ to = svalue(m.e.to[[obs.i]]),
+ sink = svalue(m.e.sink[[obs.i]]))
+ if(spec[[obs.i]]$to == "") spec[[obs.i]]$to = NULL
+ names(spec)[[obs.i]] <- svalue(m.e.obs[[obs.i]])
+ }
+ m[[m.cur]] <<- mkinmod(use_of_ff = svalue(m.ff.gc),
+ speclist = spec)
+ m[[m.cur]]$name <<- svalue(m.name.ge)
+ update_m.df()
+ m.gtable[,] <- m.df
+}
+
+# Widget setup {{{3
+m.e.0 <- ggroup(cont = m.editor, horizontal = TRUE)
+glabel("Model name: ", cont = m.e.0)
+m.name.ge <- gedit(m[[m.cur]]$name, cont = m.e.0)
+glabel("Use of formation fractions: ", cont = m.e.0)
+m.ff.gc <- gcombobox(c("min", "max"), cont = m.e.0)
+svalue(m.ff.gc) <- m[[m.cur]]$use_of_ff
+
+# Model handling buttons {{{4
+m.e.b <- ggroup(cont = m.editor, horizontal = TRUE)
+gbutton("Copy model", cont = m.e.b, handler = copy_model_handler)
+gbutton("Delete model", cont = m.e.b, handler = delete_model_handler)
+gbutton("Add transformation product", cont = m.e.b,
+ handler = add_observed_handler)
+gbutton("Save changes", cont = m.e.b, handler = save_m_changes_handler)
+
+
+m.observed <- names(m[[m.cur]]$spec)
+m.e.rows <- m.e.obs <- m.e.type <- m.e.to <- m.e.sink <- list()
+obs.to <- ""
+
+# Show the model specification {{{4
+show_m_spec <- function() {
+ for (obs.i in 1:length(m.observed)) {
+ m.e.rows[[obs.i]] <<- ggroup(cont = m.editor, horizontal = TRUE)
+ m.e.obs[[obs.i]] <<- gcombobox(observed.all, selected = obs.i,
+ cont = m.e.rows[[obs.i]])
+ m.e.type[[obs.i]] <<- gcombobox(c("SFO", "FOMC", "DFOP", "HS", "SFORB"),
+ cont = m.e.rows[[obs.i]])
+ svalue(m.e.type[[obs.i]]) <<- m[[m.cur]]$spec[[obs.i]]$type
+ glabel("to", cont = m.e.rows[[obs.i]])
+ obs.to <<- ifelse(is.null(m[[m.cur]]$spec[[obs.i]]$to), "",
+ m[[m.cur]]$spec[[obs.i]]$to)
+ m.e.to[[obs.i]] <<- gedit(obs.to, cont = m.e.rows[[obs.i]])
+ m.e.sink[[obs.i]] <<- gcheckbox("Path to sink", checked = m[[m.cur]]$spec[[obs.i]]$sink,
+ cont = m.e.rows[[obs.i]])
+ if (obs.i > 1) {
+ gbutton("Remove compound", handler = remove_compound_handler,
+ action = obs.i, cont = m.e.rows[[obs.i]])
+ }
+ }
+}
+show_m_spec()
+
+# Update the model editor {{{3
+update_m_editor <- function() {
+ svalue(m.editor) <- paste("Model", m.cur)
+ svalue(m.name.ge) <- m[[m.cur]]$name
+ svalue(m.ff.gc) <- m[[m.cur]]$use_of_ff
+ for (oldrow.i in 1:length(m.e.rows)) {
+ delete(m.editor, m.e.rows[[oldrow.i]])
+ }
+ m.observed <<- names(m[[m.cur]]$spec)
+ m.e.rows <<- m.e.obs <<- m.e.type <<- m.e.to <<- m.e.sink <<- list()
+ show_m_spec()
+}
+
+# 3}}}
+# 2}}}
+# 1}}}
+
+# vim: set foldmethod=marker ts=2 sw=2 expandtab:
|