From 8e53a2fd6ad0d19e0c20f0440407d02548dd7f9b Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Tue, 11 May 2021 06:54:56 -0500 Subject: [PATCH 01/31] re-start development versioning --- DESCRIPTION | 2 +- NEWS.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index a40a74ed..3a7908d5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: mrgsolve Title: Simulate from ODE-Based Models -Version: 0.11.1 +Version: 0.11.1.9000 Authors@R: c(person(given = "Kyle T", family = "Baron", role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index 2546d1df..4b5d41ca 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,5 @@ +# mrgsolve (development version) + # mrgsolve 0.11.1 - `mrgsim()` will now periodically check for user interrupt signal so that From 8fb00187dc26a49701058651659a893964845e0e Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Wed, 19 May 2021 08:13:52 -0500 Subject: [PATCH 02/31] scale cent by v1 not v2 --- inst/maintenance/unit/test-modlib.R | 5 +++++ inst/models/pk2iv.cpp | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/inst/maintenance/unit/test-modlib.R b/inst/maintenance/unit/test-modlib.R index 4cfea92d..2369a349 100644 --- a/inst/maintenance/unit/test-modlib.R +++ b/inst/maintenance/unit/test-modlib.R @@ -100,3 +100,8 @@ test_that("all modlib models", { expect_is(x[[1]],"mrgmod") expect_is(x[[2]],"mrgsims") }) + +test_that("pk2iv uses V1 to scale CENT", { + x <- readLines(file.path(modlib(), "pk2iv.cpp")) + expect_match(x, "#define CP (CENT/V1)", fixed = TRUE, all = FALSE) +}) diff --git a/inst/models/pk2iv.cpp b/inst/models/pk2iv.cpp index c5291b3d..e8d0a20b 100644 --- a/inst/models/pk2iv.cpp +++ b/inst/models/pk2iv.cpp @@ -9,10 +9,9 @@ CENT : Central compartment (mass) PERIPH : Peripheral compartment (mass) $GLOBAL -#define CP (CENT/V2) +#define CP (CENT/V1) $PKMODEL ncmt = 2, depot = FALSE $CAPTURE @annotated CP : Plasma concentration (mass/time) - From f88767aad2c2bc9ef283ca62a830284beb23dc7b Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Wed, 19 May 2021 08:54:32 -0500 Subject: [PATCH 03/31] update NEWS --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index 4b5d41ca..0cf226b4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # mrgsolve (development version) +- In `pk2iv`, change scaling volume for `CENT` from `V2` (incorrect) to + `V1` (#831, #832, #833) + # mrgsolve 0.11.1 - `mrgsim()` will now periodically check for user interrupt signal so that From 218ff22e68deb220b48f798e666b81f586373eed Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Mon, 28 Jun 2021 09:12:33 -0500 Subject: [PATCH 04/31] typo; soloc --- R/funset.R | 6 +++--- inst/maintenance/unit/test-mread.R | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/R/funset.R b/R/funset.R index ac5d979b..d7bcddd1 100644 --- a/R/funset.R +++ b/R/funset.R @@ -19,10 +19,10 @@ FUNSET_ERROR__ <- ' There was a problem accessing the model shared object. - Either the model object is corrupted or the model was + Either the model object was corrupted or the model was not properly compiled and/or loaded. If the model is - not loaded, use loadso(mod) to do so. This is usually - required for parallel simuilation on a worker node that + not loaded, use `loadso(mod)` to do so. This is usually + required for parallel simulation on a worker node that was not forked (e.g. when using future::multisession). Also check mrgsolve:::funset(mod) for more information. ' diff --git a/inst/maintenance/unit/test-mread.R b/inst/maintenance/unit/test-mread.R index 15415547..3e064503 100644 --- a/inst/maintenance/unit/test-mread.R +++ b/inst/maintenance/unit/test-mread.R @@ -70,7 +70,7 @@ $SIGMA @block ' -mod <- suppressWarnings(mcode("test2",code, warn=TRUE, soloc = '.')) +mod <- suppressWarnings(mcode("test2",code, warn=TRUE)) test_that("Parameters are parsed properly with mread", { expect_equal(param(mod)$CL,1) From 5bfa121c9d05f31d7236ab2e8946caa66cd52997 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Mon, 28 Jun 2021 09:13:31 -0500 Subject: [PATCH 05/31] linting test file --- inst/maintenance/unit/test-mread.R | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/inst/maintenance/unit/test-mread.R b/inst/maintenance/unit/test-mread.R index 3e064503..2657e092 100644 --- a/inst/maintenance/unit/test-mread.R +++ b/inst/maintenance/unit/test-mread.R @@ -1,4 +1,4 @@ -# Copyright (C) 2013 - 2019 Metrum Research Group, LLC +# Copyright (C) 2013 - 2021 Metrum Research Group # # This file is part of mrgsolve. # @@ -116,14 +116,12 @@ test_that("Sigma matrices are properly parsed", { expect_equivalent(mat[3,2],0.002) }) - test_that("EPS values have proper variance", { set.seed(8282) out <- mrgsim(mod,end=100000, delta=1, init = list(GUT = 0, CENT = 0)) expect_equal(round(var(out$EPS1),2),0.55) }) - test_that("Error when code is passed as project", { expect_error(suppressWarnings(mread("hey",code))) }) @@ -136,4 +134,3 @@ test_that("Error with duplicate blocks", { expect_error(mcode("a", "$MAIN \n $MAIN",compile = FALSE)) expect_error(mcode("a", "$SET \n $SET",compile = FALSE)) }) - From 0d0facae5a8b47bf79f19891fd5c9e0667614a85 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Wed, 30 Jun 2021 17:28:39 -0500 Subject: [PATCH 06/31] bump the version after some typo fixes --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3a7908d5..ac00ec18 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: mrgsolve Title: Simulate from ODE-Based Models -Version: 0.11.1.9000 +Version: 0.11.1.9001 Authors@R: c(person(given = "Kyle T", family = "Baron", role = c("aut", "cre"), From 2a3f711d1bb94e81fb039e26506cec15d332646c Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Thu, 22 Jul 2021 21:26:50 -0500 Subject: [PATCH 07/31] re-factor some recover information --- R/class_build.R | 48 +++++++++++++++--------------- R/mread.R | 2 +- R/utils.R | 6 ++++ inst/maintenance/unit/test-mread.R | 18 ++++++++++- 4 files changed, 48 insertions(+), 26 deletions(-) diff --git a/R/class_build.R b/R/class_build.R index 0c13dd9c..fcf5aeb3 100644 --- a/R/class_build.R +++ b/R/class_build.R @@ -209,20 +209,26 @@ build_output_cleanup <- function(x,build) { patt <- "^ *In function .*void _model.*:$" errr <- msub(pattern = patt, replacement = "", x = errr) x[["stderr"]] <- errr - x <- structure(x, class = "mrgsolve-build-error") + x <- structure(x, class = c("mrgsolve-build-error", "list")) x } - -build_failed <- function(out,build,mod,ignore.stdout) { - outt <- list(out) - names(outt) <- paste0("mrgsolve.build.", build[["model"]]) - options(outt) +build_failed <- function(out,build,mod,spec,ignore.stdout) { out <- build_output_cleanup(out,build) - if(build[["recover"]]) { + if(isTRUE(build[["recover"]])) { warning("returning object for debugging purposes only.") - ans <- list(build = build, mod = as.list(mod), shlib=list(compiled=FALSE), out=out) - return(structure(ans,class = "mrgsolve-build-recover")) + build <- as.list(build) + mod <- as.list(mod) + mod[["envir"]] <- as.list(mod[["envir"]]) + mod[["shlib"]][["version"]] <- unlist(mod[["shlib"]][["version"]]) + mod[["shlib"]][["compiled"]] <- FALSE + ans <- list( + out = out, + build = build, + mod = mod, + spec = spec + ) + return(structure(ans, class = c("mrgsolve-build-recover", "list"))) } if(!ignore.stdout) { msg <- divider_msg("stdout") @@ -241,22 +247,16 @@ build_failed <- function(out,build,mod,ignore.stdout) { stop("the model build step failed.",call.=FALSE) } - -build_save_output <- function(out) { - out[["date"]] <- date() - path <- file.path(tempdir(), "mrgsolve-build-result.RDS") - saveRDS(out, file=path) - return(invisible(path)) -} - -build_get_output <- function() { - file <- file.path(tempdir(),"mrgsolve-build-result.RDS") - file <- normalizePath(file,mustWork=FALSE) - if(!file.exists(file)) { - message("No build output was found.") - return(invisible(list())) +build_format_recover <- function(data, path = NULL) { + if(!requireNamespace("yaml")) { + stop("please install the yaml package to format recovery data", call.=FALSE) + } + ans <- yaml::as.yaml(data) + if(is.character(path)) { + writeLines(text = ans, con = path) + return(invisible(ans)) } - return(readRDS(file)) + ans } build_handle_127 <- function(out) { diff --git a/R/mread.R b/R/mread.R index ce6fab32..5cd9cb11 100644 --- a/R/mread.R +++ b/R/mread.R @@ -539,7 +539,7 @@ mread <- function(model, project = getOption("mrgsolve.project", getwd()), if(!comp_success) { if(ignore.stdout) message("error.\n", appendLF=FALSE) - return(build_failed(out,build,x,ignore.stdout)) + return(build_failed(out,build,x,spec,ignore.stdout)) } if(ignore.stdout) { diff --git a/R/utils.R b/R/utils.R index 80bdacb8..aff79b96 100644 --- a/R/utils.R +++ b/R/utils.R @@ -570,7 +570,13 @@ system4 <- function(cmd, args=character(0), pattern, path) { files <- file.path(path, paste0("system4__",c("stdout","stderr"),"__", pattern)) x <- list(status=system2(cmd, args, stdout = files[1], stderr = files[2])) x[["stdout"]] <- readLines(files[1]) + if(length(x[["stdout"]])==0) { + x[["stdout"]] <- "stdout could not be recovered after system4 call" + } x[["stderr"]] <- readLines(files[2]) + if(length(x[["stderr"]])==0) { + x[["stderr"]] <- "stderr could not be recovered after system4 call" + } x } diff --git a/inst/maintenance/unit/test-mread.R b/inst/maintenance/unit/test-mread.R index 2657e092..b207d2cc 100644 --- a/inst/maintenance/unit/test-mread.R +++ b/inst/maintenance/unit/test-mread.R @@ -127,10 +127,26 @@ test_that("Error when code is passed as project", { }) test_that("Model name with spaces is error", { - expect_error(mcode("ab cd", "")) + expect_error(mcode("ab cd", "")) }) test_that("Error with duplicate blocks", { expect_error(mcode("a", "$MAIN \n $MAIN",compile = FALSE)) expect_error(mcode("a", "$SET \n $SET",compile = FALSE)) }) + +test_that("Recover data when compile fails", { + code <- '[main] double a = 2\n[param] b = 5\n' + expect_warning( + mod <- mcode("fail", code, recover = TRUE), + regexp = "returning object for debugging purposes only" + ) + expect_is(mod, "list") + expect_named(mod) + expect_true("mod" %in% names(mod)) + expect_true("build" %in% names(mod)) + expect_true("out" %in% names(mod)) + expect_true("spec" %in% names(mod)) + recov <- mrgsolve:::build_format_recover(data) + expect_is(recov, "character") +}) From f7ce0459690a835cac7c38cf84d035c6fd5797d5 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Thu, 22 Jul 2021 21:28:32 -0500 Subject: [PATCH 08/31] doc --- R/mread.R | 5 +++-- man/mread.Rd | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/R/mread.R b/R/mread.R index 5cd9cb11..578ef56c 100644 --- a/R/mread.R +++ b/R/mread.R @@ -48,8 +48,9 @@ NULL #' @param quiet don't print messages when compiling #' @param preclean logical; if \code{TRUE}, compilation artifacts are #' cleaned up first -#' @param recover if \code{TRUE}, an object will be returned in case -#' the model shared object fails to build +#' @param recover if \code{TRUE}, a list of build will be returned in case +#' the model shared object fails to compile; use this option to and +#' the returned object to collect information assist in debugging #' @param capture a character vector or comma-separated string of additional #' model variables to capture; these variables will be added to the capture #' list for the current call to \code{\link{mread}} only diff --git a/man/mread.Rd b/man/mread.Rd index aab5223d..4f8a2503 100644 --- a/man/mread.Rd +++ b/man/mread.Rd @@ -81,8 +81,9 @@ list for the current call to \code{\link{mread}} only} \item{preclean}{logical; if \code{TRUE}, compilation artifacts are cleaned up first} -\item{recover}{if \code{TRUE}, an object will be returned in case -the model shared object fails to build} +\item{recover}{if \code{TRUE}, a list of build will be returned in case +the model shared object fails to compile; use this option to and +the returned object to collect information assist in debugging} \item{...}{passed to \code{\link[mrgsolve]{update}}; also arguments passed to mread from \code{\link{mread_cache}}.} From e37997e9e608d66f4b3849af2d77e24579d98ac7 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Sat, 24 Jul 2021 08:32:19 -0500 Subject: [PATCH 09/31] fix test --- inst/maintenance/unit/test-mread.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/inst/maintenance/unit/test-mread.R b/inst/maintenance/unit/test-mread.R index b207d2cc..414c1de5 100644 --- a/inst/maintenance/unit/test-mread.R +++ b/inst/maintenance/unit/test-mread.R @@ -147,6 +147,8 @@ test_that("Recover data when compile fails", { expect_true("build" %in% names(mod)) expect_true("out" %in% names(mod)) expect_true("spec" %in% names(mod)) - recov <- mrgsolve:::build_format_recover(data) + recov <- mrgsolve:::build_format_recover(mod) expect_is(recov, "character") + recov_list <- yaml::yaml.load(recov) + expect_is(recov_list, "list") }) From 77395eae5441ab8a110f74433f5376abe3bc70e6 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Fri, 30 Jul 2021 08:39:55 -0500 Subject: [PATCH 10/31] convert to data frame with Rcpp --- R/mrgsim_q.R | 7 ++++--- R/mrgsolve.R | 20 ++++++++------------ inst/include/mrgsolve.h | 2 ++ man/qsim.Rd | 5 +++-- src/devtran.cpp | 2 +- src/mrgsolve.cpp | 13 +++++++++++++ 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/R/mrgsim_q.R b/R/mrgsim_q.R index 92e0995a..aeae4003 100644 --- a/R/mrgsim_q.R +++ b/R/mrgsim_q.R @@ -157,13 +157,14 @@ mrgsim_q <- function(x, PACKAGE = "mrgsolve" )[["data"]] - dimnames(out) <- list(NULL, c("ID", tcol,x@cmtL,x@capL)) + names(out) <- c("ID", tcol,x@cmtL,x@capL) if(output=="df") { - return(as.data.frame(out)) + return(out) } + if(output=="matrix") { - return(out) + return(as.matrix(out)) } new( diff --git a/R/mrgsolve.R b/R/mrgsolve.R index 81328676..37b677e6 100644 --- a/R/mrgsolve.R +++ b/R/mrgsolve.R @@ -687,12 +687,7 @@ do_mrgsim <- function(x, cnames <- new_names } - dimnames(out[["data"]]) <- list(NULL, cnames) - - ans <- as.data.frame.matrix( - out[["data"]], - stringsAsFactors = FALSE - ) + ans <- setNames(out[["data"]], cnames) if(do_recover_data || do_recover_idata) { if(do_recover_data) { @@ -730,7 +725,8 @@ do_mrgsim <- function(x, #' Basic, simple simulation from model object #' -#' This is just a lighter version of [mrgsim], with fewer options. See `Details`. +#' This is just a lighter version of [mrgsim()], with fewer options. +#' See `Details`. #' #' @inheritParams mrgsim #' @@ -758,7 +754,7 @@ do_mrgsim <- function(x, #' #' out <- qsim(mod,dose) #' -#' @seealso [mrgsim_q], [mrgsim], [mrgsim_variants] +#' @seealso [mrgsim_q()], [mrgsim()], [mrgsim_variants] #' #' @md #' @@ -846,17 +842,17 @@ qsim <- function(x, ) if(tad) tcol <- c(tcol,"tad") - - dimnames(out[["data"]]) <- list(NULL, c("ID", tcol, x@cmtL, x@capL)) + + names(out[["data"]]) <- c("ID", tcol, x@cmtL, x@capL) if(output=="df") { - return(as.data.frame.matrix(out[["data"]])) + return(out[["data"]]) } new( "mrgsims", request=x@cmtL, - data=as.data.frame.matrix(out[["data"]]), + data=out[["data"]], outnames=x@capL, mod=x ) diff --git a/inst/include/mrgsolve.h b/inst/include/mrgsolve.h index 857d04f5..b852d7f7 100644 --- a/inst/include/mrgsolve.h +++ b/inst/include/mrgsolve.h @@ -61,6 +61,8 @@ Rcpp::NumericMatrix EXPAND_EVENTS(const Rcpp::IntegerVector& idcol_, const Rcpp::NumericMatrix& events, const Rcpp::NumericVector& id); +Rcpp::List mat2df(Rcpp::NumericMatrix& x); + // Rcpp::NumericMatrix recdata(Rcpp::NumericMatrix& dose, // Rcpp::NumericMatrix& obs, // Rcpp::IntegerVector& cols, diff --git a/man/qsim.Rd b/man/qsim.Rd index c0382c21..2ece8572 100644 --- a/man/qsim.Rd +++ b/man/qsim.Rd @@ -64,7 +64,8 @@ default output object; other options include \code{df} (for data.frame) or \code{matrix}} } \description{ -This is just a lighter version of \link{mrgsim}, with fewer options. See \code{Details}. +This is just a lighter version of \code{\link[=mrgsim]{mrgsim()}}, with fewer options. +See \code{Details}. } \details{ There is no pipeline interface for this function; all configuration options @@ -84,5 +85,5 @@ out <- qsim(mod,dose) } \seealso{ -\link{mrgsim_q}, \link{mrgsim}, \link{mrgsim_variants} +\code{\link[=mrgsim_q]{mrgsim_q()}}, \code{\link[=mrgsim]{mrgsim()}}, \link{mrgsim_variants} } diff --git a/src/devtran.cpp b/src/devtran.cpp index 8c8dfb58..1458f67e 100644 --- a/src/devtran.cpp +++ b/src/devtran.cpp @@ -640,6 +640,6 @@ Rcpp::List DEVTRAN(const Rcpp::List parin, if((tscale != 1) && (tscale >= 0)) { ans(Rcpp::_,1) = ans(Rcpp::_,1) * tscale; } - return Rcpp::List::create(Rcpp::Named("data") = ans, + return Rcpp::List::create(Rcpp::Named("data") = mat2df(ans), Rcpp::Named("trannames") = tran_names); } diff --git a/src/mrgsolve.cpp b/src/mrgsolve.cpp index 42cd032d..6fff131d 100644 --- a/src/mrgsolve.cpp +++ b/src/mrgsolve.cpp @@ -388,6 +388,19 @@ Rcpp::List EXPAND_OBSERVATIONS( Rcpp::Named("index") = index); } +Rcpp::List mat2df(Rcpp::NumericMatrix& x) { + Rcpp::List ret(x.ncol()); + for(int i = 0; i < x.ncol(); ++i) { + ret[i] = x(Rcpp::_,i); + } + Rcpp::IntegerVector rn(2); + rn[0] = NA_INTEGER; + rn[1] = x.nrow()*-1; + ret.attr("class") = "data.frame"; + ret.attr("row.names") = rn; + return ret; +} + #endif From c41d7a3477e089b3cdf5da3f6f2919ab731651fb Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Tue, 3 Aug 2021 14:19:58 -0500 Subject: [PATCH 11/31] names --- R/mrgsolve.R | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/R/mrgsolve.R b/R/mrgsolve.R index 37b677e6..b67dc245 100644 --- a/R/mrgsolve.R +++ b/R/mrgsolve.R @@ -637,7 +637,7 @@ do_mrgsim <- function(x, capture.output(file=capture, append=TRUE, print(data)) capture.output(file=capture, append=TRUE, print(carry_out)) } - + out <- .Call( `_mrgsolve_DEVTRAN`, parin, @@ -654,11 +654,10 @@ do_mrgsim <- function(x, PACKAGE = "mrgsolve" ) - # out$trannames always comes back lower case in a specific order # need to rename to get back to requested case # Then, rename again for user-supplied renaming - carry.tran <- .ren.rename(rename.carry.tran,out[["trannames"]]) + carry.tran <- .ren.rename(rename.carry.tran, out[["trannames"]]) if(tad) tcol <- c(tcol,"tad") @@ -686,8 +685,9 @@ do_mrgsim <- function(x, } cnames <- new_names } - - ans <- setNames(out[["data"]], cnames) + + ans <- out[["data"]] + names(ans) <- cnames if(do_recover_data || do_recover_idata) { if(do_recover_data) { From 8a2f5f9e59543daa080f3e352746f87f549641e3 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Tue, 3 Aug 2021 14:21:07 -0500 Subject: [PATCH 12/31] linting --- R/mrgsolve.R | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/R/mrgsolve.R b/R/mrgsolve.R index b67dc245..d6bb7998 100644 --- a/R/mrgsolve.R +++ b/R/mrgsolve.R @@ -717,9 +717,9 @@ do_mrgsim <- function(x, new( "mrgsims", request = x@cmtL, - data=ans, - outnames=x@capL, - mod=x + data = ans, + outnames = x@capL, + mod = x ) } @@ -851,10 +851,10 @@ qsim <- function(x, new( "mrgsims", - request=x@cmtL, - data=out[["data"]], - outnames=x@capL, - mod=x + request = x@cmtL, + data = out[["data"]], + outnames = x@capL, + mod = x ) } From 1707ee7746ac29fbb88c50ab06df66ede71d89c7 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Tue, 3 Aug 2021 14:40:09 -0500 Subject: [PATCH 13/31] add test for requesting matrix while recovering character data --- R/mrgsolve.R | 18 ++++++++++-------- tests/testthat/test-carry_out.R | 9 +++++++++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/R/mrgsolve.R b/R/mrgsolve.R index d6bb7998..33d4695d 100644 --- a/R/mrgsolve.R +++ b/R/mrgsolve.R @@ -686,38 +686,40 @@ do_mrgsim <- function(x, cnames <- new_names } - ans <- out[["data"]] - names(ans) <- cnames + names(out[["data"]]) <- cnames if(do_recover_data || do_recover_idata) { if(do_recover_data) { if(!rename.recov$identical) { names(join_data) <- .ren.rename(rename.recov,names(join_data)) } - ans <- left_join(ans,join_data,by=".data_row.",suffix=c("", ".recov")) - ans$.data_row. <- NULL + out[["data"]] <- left_join(out[["data"]],join_data,by=".data_row.",suffix=c("", ".recov")) + out[["data"]][[".data_row."]] <- NULL } if(do_recover_idata) { if(!rename.recov$identical) { names(join_idata) <- .ren.rename(rename.recov,names(join_idata)) } - ans <- left_join(ans,join_idata,by="ID",suffix=c("", ".recov")) + out[["data"]] <- left_join(out[["data"]],join_idata,by="ID",suffix=c("", ".recov")) } } if(!is.null(output)) { if(output=="df") { - return(ans) + return(out[["data"]]) } if(output=="matrix") { - return(out[["data"]]) + if(!all(sapply(out[["data"]], is.numeric))) { + stop("can't return matrix because non-numeric data was found.", call.=FALSE) + } + return(data.matrix(out[["data"]])) } } new( "mrgsims", request = x@cmtL, - data = ans, + data = out[["data"]], outnames = x@capL, mod = x ) diff --git a/tests/testthat/test-carry_out.R b/tests/testthat/test-carry_out.R index d18de26a..3fd3b68b 100644 --- a/tests/testthat/test-carry_out.R +++ b/tests/testthat/test-carry_out.R @@ -106,3 +106,12 @@ test_that("recover input idata-set items", { expect_is(out$b,"character") expect_error(mrgsim_e(mod,idata,recover="b",carry_out="b")) }) + +test_that("error to request matrix and recover character data", { + data <- expand.ev(amt = 100, group = "A") + expect_is(mrgsim(mod, data, recover = "group"), "mrgsims") + expect_error( + mrgsim(mod, data, recover = "group", output = "matrix"), + msg = "can't return matrix because non-numeric data was found" + ) +}) From 731947f7c6d183e2c7eabab6214426a9ff23d321 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Tue, 3 Aug 2021 14:47:03 -0500 Subject: [PATCH 14/31] some linting --- R/mrgsim_q.R | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/R/mrgsim_q.R b/R/mrgsim_q.R index aeae4003..4ef16b3a 100644 --- a/R/mrgsim_q.R +++ b/R/mrgsim_q.R @@ -157,7 +157,7 @@ mrgsim_q <- function(x, PACKAGE = "mrgsolve" )[["data"]] - names(out) <- c("ID", tcol,x@cmtL,x@capL) + names(out) <- c("ID", tcol, x@cmtL, x@capL) if(output=="df") { return(out) @@ -169,9 +169,9 @@ mrgsim_q <- function(x, new( "mrgsims", - request=x@cmtL, - data=as.data.frame(out), - outnames=x@capL, - mod=x + request = x@cmtL, + data = out, + outnames = x@capL, + mod = x ) } From 82cc71189262ede2d8c03464bb12265dbb5ce88b Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Wed, 4 Aug 2021 23:11:00 -0500 Subject: [PATCH 15/31] const matrix to mat2df --- inst/include/mrgsolve.h | 2 +- src/mrgsolve.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inst/include/mrgsolve.h b/inst/include/mrgsolve.h index b852d7f7..ddf91c5d 100644 --- a/inst/include/mrgsolve.h +++ b/inst/include/mrgsolve.h @@ -61,7 +61,7 @@ Rcpp::NumericMatrix EXPAND_EVENTS(const Rcpp::IntegerVector& idcol_, const Rcpp::NumericMatrix& events, const Rcpp::NumericVector& id); -Rcpp::List mat2df(Rcpp::NumericMatrix& x); +Rcpp::List mat2df(Rcpp::NumericMatrix const& x); // Rcpp::NumericMatrix recdata(Rcpp::NumericMatrix& dose, // Rcpp::NumericMatrix& obs, diff --git a/src/mrgsolve.cpp b/src/mrgsolve.cpp index 6fff131d..f2ca0818 100644 --- a/src/mrgsolve.cpp +++ b/src/mrgsolve.cpp @@ -388,7 +388,7 @@ Rcpp::List EXPAND_OBSERVATIONS( Rcpp::Named("index") = index); } -Rcpp::List mat2df(Rcpp::NumericMatrix& x) { +Rcpp::List mat2df(Rcpp::NumericMatrix const& x) { Rcpp::List ret(x.ncol()); for(int i = 0; i < x.ncol(); ++i) { ret[i] = x(Rcpp::_,i); From 98a6dc1bbffe8bbd3a6e1c7e4d0a6d3a27cc1621 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Wed, 25 Aug 2021 07:50:12 -0500 Subject: [PATCH 16/31] fix omega collate issue --- R/matlist.R | 14 +++++++------- src/RcppExports.cpp | 5 +++++ src/mrgsolve.cpp | 4 ++++ 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/R/matlist.R b/R/matlist.R index 52ea03b6..7784b782 100644 --- a/R/matlist.R +++ b/R/matlist.R @@ -200,7 +200,6 @@ setMethod("smat", "mrgsims", function(.x,make=FALSE,...) { as.matrix(mod(.x)@sigma) }) - #' Zero out random effects in a model object #' #' Sets all elements of the OMEGA or SIGMA matrix to zero @@ -261,7 +260,7 @@ setMethod("as.list", "matlist", function(x, ...) x@data) #' @export setMethod("as.matrix", "matlist", function(x, ...) { if(length(x@data)==0) return(matrix(nrow=0,ncol=0)) - SUPERMATRIX(x@data, ...) + SUPERMATRIX(x@data, ..., keep_names = FALSE) }) #' @rdname matlist @@ -335,13 +334,14 @@ cumoffset <- function(x) { ##' @rdname matlist_ops ##' @export setMethod("c", "matlist", function(x,...,recursive=FALSE) { - what <- c(list(x),list(...)) - stopifnot(all(sapply(what,is.matlist))) + what <- c(list(x), list(...)) + stopifnot(all(sapply(what, is.matlist))) + what <- what[sapply(what, slot, name = "n") > 0] if(length(what)==1) return(x) - d <- lapply(what,as.matrix) - d <- setNames(d,sapply(what,names)) + d <- lapply(what, as.matrix) + d <- setNames(d, sapply(what, names)) l <- sapply(unname(what), labels) - create_matlist(d,labels=l, class=class(x)[1]) + create_matlist(d, labels = l, class = class(x)[1]) }) collapse_matrix <- function(x,class) { diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index 7b6b645d..e64d5bde 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -7,6 +7,11 @@ using namespace Rcpp; +#ifdef RCPP_USE_GLOBAL_ROSTREAM +Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get(); +Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); +#endif + // DEVTRAN Rcpp::List DEVTRAN(const Rcpp::List parin, const Rcpp::NumericVector& inpar, const Rcpp::CharacterVector& parnames, const Rcpp::NumericVector& init, Rcpp::CharacterVector& cmtnames, const Rcpp::IntegerVector& capture, const Rcpp::List& funs, const Rcpp::NumericMatrix& data, const Rcpp::NumericMatrix& idata, Rcpp::NumericMatrix& OMEGA, Rcpp::NumericMatrix& SIGMA, Rcpp::Environment envir); RcppExport SEXP _mrgsolve_DEVTRAN(SEXP parinSEXP, SEXP inparSEXP, SEXP parnamesSEXP, SEXP initSEXP, SEXP cmtnamesSEXP, SEXP captureSEXP, SEXP funsSEXP, SEXP dataSEXP, SEXP idataSEXP, SEXP OMEGASEXP, SEXP SIGMASEXP, SEXP envirSEXP) { diff --git a/src/mrgsolve.cpp b/src/mrgsolve.cpp index f2ca0818..3e92f126 100644 --- a/src/mrgsolve.cpp +++ b/src/mrgsolve.cpp @@ -150,6 +150,10 @@ void dcorr(Rcpp::NumericMatrix& x) { //[[Rcpp::export]] Rcpp::NumericMatrix SUPERMATRIX(const Rcpp::List& a, bool keep_names) { + if(a.size()==1) { + return a[0]; + } + int j,k; Rcpp::NumericMatrix mat; From 5ad2bd644092cdf5d4bb8650ddab3a74d4598d01 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Wed, 25 Aug 2021 08:17:02 -0500 Subject: [PATCH 17/31] adding tests for SUPERMATRIX --- R/matrix.R | 5 +++-- tests/testthat/test-matrix.R | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/R/matrix.R b/R/matrix.R index 87618816..7b56058b 100644 --- a/R/matrix.R +++ b/R/matrix.R @@ -1,5 +1,4 @@ -# Copyright (C) 2013 - 2019 Metrum Research Group, LLC -# +# Copyright (C) 2013 - 2021 Metrum Research Group # This file is part of mrgsolve. # # mrgsolve is free software: you can redistribute it and/or modify it @@ -17,6 +16,8 @@ SUPERMATRIX <- function(x,keep_names=FALSE) { + stopifnot(is.list(x)) + stopifnot(all(sapply(x, is.matrix))) x <- .Call(`_mrgsolve_SUPERMATRIX`,x,keep_names,PACKAGE="mrgsolve") if(nrow(x) > 0 & !keep_names) { dimnames(x) <- list(paste0(seq_len(nrow(x)), ": "), NULL) diff --git a/tests/testthat/test-matrix.R b/tests/testthat/test-matrix.R index c810e5f6..555d54ac 100644 --- a/tests/testthat/test-matrix.R +++ b/tests/testthat/test-matrix.R @@ -31,7 +31,18 @@ test_that("Testing modMATRIX", { expect_equal(modMATRIX("0 0 0", use=FALSE), matrix(0,nrow=3,ncol=3)) }) - - - - +test_that("SUPERMATRIX", { + ml <- list(matrix(1, 2, 2), matrix(3, 4, 4)) + dimnames(ml[[1]]) <- list(c("a", "b"), c("A", "B")) + ans <- mrgsolve:::SUPERMATRIX(ml) + expect_is(ans, "matrix") + expect_equal(dim(ans), c(6, 6)) + ml$a <- "a" + expect_error(mrgsolve:::SUPERMATRIX(ml), msg = "is not TRUE") + expect_error(mrgsolve:::SUPERMATRIX(ml[[1]]), msg = "is not TRUE") + ml$a <- NULL + ans <- mrgsolve:::SUPERMATRIX(ml[2]) + expect_identical(unname(ml[[2]]),unname(ans)) + ans <- mrgsolve:::SUPERMATRIX(ml[1], keep_names=TRUE) + expect_identical(ans, ml[[1]]) +}) From 322e84efbc55a69d7bb8d8b7a450b8e58292af84 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Wed, 25 Aug 2021 08:21:49 -0500 Subject: [PATCH 18/31] don't force keep_names --- R/matlist.R | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/R/matlist.R b/R/matlist.R index 7784b782..fff1d7cd 100644 --- a/R/matlist.R +++ b/R/matlist.R @@ -259,8 +259,10 @@ setMethod("as.list", "matlist", function(x, ...) x@data) #' @rdname matlist #' @export setMethod("as.matrix", "matlist", function(x, ...) { - if(length(x@data)==0) return(matrix(nrow=0,ncol=0)) - SUPERMATRIX(x@data, ..., keep_names = FALSE) + if(length(x@data)==0) { + return(matrix(nrow = 0, ncol = 0)) + } + SUPERMATRIX(x@data, ...) }) #' @rdname matlist From 18d82af8267ddac98962af2b75158461a5faa10b Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Sun, 29 Aug 2021 07:59:00 -0500 Subject: [PATCH 19/31] SUPERMATRIX tests; clean up --- R/class_matlist.R | 2 +- R/matrix.R | 1 - tests/testthat/test-matlist.R | 8 ++++---- tests/testthat/test-matrix.R | 4 ++++ 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/R/class_matlist.R b/R/class_matlist.R index 470d5599..ab8e5201 100644 --- a/R/class_matlist.R +++ b/R/class_matlist.R @@ -47,7 +47,7 @@ valid.matlist <- function(object) { } if(!x4) { - y <- which(sapply(object@data, det) < 0) + y <- which(!sapply(object@data, det) > 0) message("Problem with this matrix:") print(object@data[y]) out <- c(out, "Invalid matrix: determinant is less than 0.") diff --git a/R/matrix.R b/R/matrix.R index 7b56058b..05b0312f 100644 --- a/R/matrix.R +++ b/R/matrix.R @@ -14,7 +14,6 @@ # You should have received a copy of the GNU General Public License # along with mrgsolve. If not, see . - SUPERMATRIX <- function(x,keep_names=FALSE) { stopifnot(is.list(x)) stopifnot(all(sapply(x, is.matrix))) diff --git a/tests/testthat/test-matlist.R b/tests/testthat/test-matlist.R index dde2031d..273792b5 100644 --- a/tests/testthat/test-matlist.R +++ b/tests/testthat/test-matlist.R @@ -49,10 +49,10 @@ test_that("Indexing SIGMA matrix elements", { expect_equivalent(as.matrix(smat(mod))[3,3],0.3) }) -o1 <- - omat(diag(c(1.1, 2.2, 3.3)), - diag(c(4.4, 5.5, 6.6)), - matrix(seq(91,99),nrow=3, byrow=TRUE)) +a <- diag(c(1.1, 2.2, 3.3)) +b <- diag(c(4.4, 5.5, 6.6)) +c <- matrix(seq(91,99),nrow = 3, byrow = TRUE) +o1 <- omat(a,b,c) mat <- as.matrix(o1) diff --git a/tests/testthat/test-matrix.R b/tests/testthat/test-matrix.R index 555d54ac..18ce57fc 100644 --- a/tests/testthat/test-matrix.R +++ b/tests/testthat/test-matrix.R @@ -45,4 +45,8 @@ test_that("SUPERMATRIX", { expect_identical(unname(ml[[2]]),unname(ans)) ans <- mrgsolve:::SUPERMATRIX(ml[1], keep_names=TRUE) expect_identical(ans, ml[[1]]) + ans1 <- mrgsolve:::SUPERMATRIX(list()) + expect_identical(ans1, matrix(0, nrow = 0, ncol = 0)) + ans2 <- mrgsolve:::SUPERMATRIX(omat()@data) + expect_identical(ans1, ans2) }) From be8e4edb30d5b89ed60997d707425946fbc7fe8b Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Mon, 30 Aug 2021 10:45:39 -0500 Subject: [PATCH 20/31] lint --- tests/testthat/test-matrix.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/testthat/test-matrix.R b/tests/testthat/test-matrix.R index 18ce57fc..81b1642d 100644 --- a/tests/testthat/test-matrix.R +++ b/tests/testthat/test-matrix.R @@ -43,7 +43,7 @@ test_that("SUPERMATRIX", { ml$a <- NULL ans <- mrgsolve:::SUPERMATRIX(ml[2]) expect_identical(unname(ml[[2]]),unname(ans)) - ans <- mrgsolve:::SUPERMATRIX(ml[1], keep_names=TRUE) + ans <- mrgsolve:::SUPERMATRIX(ml[1], keep_names = TRUE) expect_identical(ans, ml[[1]]) ans1 <- mrgsolve:::SUPERMATRIX(list()) expect_identical(ans1, matrix(0, nrow = 0, ncol = 0)) From ecdc975b0b3b487fcf27d88c95bb895ed1fb6159 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Mon, 30 Aug 2021 10:46:48 -0500 Subject: [PATCH 21/31] lint SUPERMATRIX --- R/matrix.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/matrix.R b/R/matrix.R index 05b0312f..ac742aa9 100644 --- a/R/matrix.R +++ b/R/matrix.R @@ -14,10 +14,10 @@ # You should have received a copy of the GNU General Public License # along with mrgsolve. If not, see . -SUPERMATRIX <- function(x,keep_names=FALSE) { +SUPERMATRIX <- function(x, keep_names = FALSE) { stopifnot(is.list(x)) stopifnot(all(sapply(x, is.matrix))) - x <- .Call(`_mrgsolve_SUPERMATRIX`,x,keep_names,PACKAGE="mrgsolve") + x <- .Call(`_mrgsolve_SUPERMATRIX`, x, keep_names, PACKAGE = "mrgsolve") if(nrow(x) > 0 & !keep_names) { dimnames(x) <- list(paste0(seq_len(nrow(x)), ": "), NULL) } From 988fa3f993841ecfd86c5a416bcda93fc73f7fec Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Mon, 30 Aug 2021 21:15:41 -0500 Subject: [PATCH 22/31] release branch --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index ac00ec18..a1eecf0d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: mrgsolve Title: Simulate from ODE-Based Models -Version: 0.11.1.9001 +Version: 0.11.1.9100 Authors@R: c(person(given = "Kyle T", family = "Baron", role = c("aut", "cre"), From d27de0998c26919bca0ea736701914b9b170489b Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Mon, 30 Aug 2021 21:23:43 -0500 Subject: [PATCH 23/31] fix typo in cmat --- NEWS.md | 6 ++++++ R/matrix.R | 4 ++-- man/matrix_converters.Rd | 2 +- man/matrix_helpers.Rd | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index 0cf226b4..571ed067 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,12 @@ - In `pk2iv`, change scaling volume for `CENT` from `V2` (incorrect) to `V1` (#831, #832, #833) + +- Fix bug collating multiple `$OMEGA` or `$SIGMA` matrices when parsing a + model (#863) + +- Refactor how debugging information is processed when using the `recover` + argument to `mread()` (#853) # mrgsolve 0.11.1 diff --git a/R/matrix.R b/R/matrix.R index ac742aa9..a8feb18d 100644 --- a/R/matrix.R +++ b/R/matrix.R @@ -132,7 +132,7 @@ Diag <- function(x) { ##' Create matrices from vector input ##' ##' @param ... matrix data -##' @param correlation logical; if TRUE, off diagonal elements are assumed +##' @param correlation logical; if TRUE, off-diagonal elements are assumed ##' to be correlations and converted to covariances ##' @param digits if greater than zero, matrix is passed to signif (along ##' with digits) prior to returning @@ -192,7 +192,7 @@ dmat <- function(...) { ##' @details ##' Use \code{as_dmat} to create a diagonal matrix, \code{as_bmat} ##' to create a block matrix, and \code{as_cmat} to create a block -##' matrix where diagonal elements are understood to be correlations +##' matrix where off-diagonal elements are understood to be correlations ##' rather than covariances. \code{as_cmat} uses \code{as_bmat} to ##' form the matrix and then converts off-diagonal elements to ##' covariances before returning. diff --git a/man/matrix_converters.Rd b/man/matrix_converters.Rd index 94b818ae..22939bb8 100644 --- a/man/matrix_converters.Rd +++ b/man/matrix_converters.Rd @@ -58,7 +58,7 @@ matrix (\code{c}). \details{ Use \code{as_dmat} to create a diagonal matrix, \code{as_bmat} to create a block matrix, and \code{as_cmat} to create a block -matrix where diagonal elements are understood to be correlations +matrix where off-diagonal elements are understood to be correlations rather than covariances. \code{as_cmat} uses \code{as_bmat} to form the matrix and then converts off-diagonal elements to covariances before returning. diff --git a/man/matrix_helpers.Rd b/man/matrix_helpers.Rd index 2fbc0810..9759c037 100644 --- a/man/matrix_helpers.Rd +++ b/man/matrix_helpers.Rd @@ -16,7 +16,7 @@ dmat(...) \arguments{ \item{...}{matrix data} -\item{correlation}{logical; if TRUE, off diagonal elements are assumed +\item{correlation}{logical; if TRUE, off-diagonal elements are assumed to be correlations and converted to covariances} \item{digits}{if greater than zero, matrix is passed to signif (along From 18fe2e9366b905704ece490733f4425b13e8e845 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Mon, 30 Aug 2021 21:23:54 -0500 Subject: [PATCH 24/31] bump --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index a1eecf0d..a280022d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: mrgsolve Title: Simulate from ODE-Based Models -Version: 0.11.1.9100 +Version: 0.11.1.9101 Authors@R: c(person(given = "Kyle T", family = "Baron", role = c("aut", "cre"), From 399fcbda31b8b170650e33e7cf38f1b13a32d4a5 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Mon, 30 Aug 2021 21:27:58 -0500 Subject: [PATCH 25/31] news --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index 571ed067..ce9b15ef 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,9 @@ - Refactor how debugging information is processed when using the `recover` argument to `mread()` (#853) + +- Fix typo in documentation for `as_cmat()`; the off-diagonals are assumed + to contain correlations (#856) # mrgsolve 0.11.1 From 4d4b09264912d7edf80c06e32ec79d4327f76693 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Tue, 31 Aug 2021 08:50:47 -0500 Subject: [PATCH 26/31] bump --- DESCRIPTION | 2 +- NEWS.md | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a280022d..e6c7995b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: mrgsolve Title: Simulate from ODE-Based Models -Version: 0.11.1.9101 +Version: 0.11.2 Authors@R: c(person(given = "Kyle T", family = "Baron", role = c("aut", "cre"), diff --git a/NEWS.md b/NEWS.md index ce9b15ef..02b09c28 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,4 @@ -# mrgsolve (development version) +# mrgsolve 0.11.2 - In `pk2iv`, change scaling volume for `CENT` from `V2` (incorrect) to `V1` (#831, #832, #833) @@ -12,6 +12,9 @@ - Fix typo in documentation for `as_cmat()`; the off-diagonals are assumed to contain correlations (#856) +- Wrote a `as.data.frame.matrix()` function in Rcpp; all simulation results + return from the C++ simulation code as a data frame (#857) + # mrgsolve 0.11.1 - `mrgsim()` will now periodically check for user interrupt signal so that From 95276bfe7db89ee8aba1f57e65930ca5b1fa5e1e Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Wed, 1 Sep 2021 22:45:37 -0500 Subject: [PATCH 27/31] fix capture validation bug --- NEWS.md | 3 +++ R/mread.R | 3 +-- inst/maintenance/unit/test-capture.R | 12 +++++++----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/NEWS.md b/NEWS.md index 02b09c28..61820f83 100644 --- a/NEWS.md +++ b/NEWS.md @@ -14,6 +14,9 @@ - Wrote a `as.data.frame.matrix()` function in Rcpp; all simulation results return from the C++ simulation code as a data frame (#857) + +- Fix bug where dynamic capture (via `mread()`) was not allowed for variables + declared in `$GLOBAL` (#868) # mrgsolve 0.11.1 diff --git a/R/mread.R b/R/mread.R index 578ef56c..4ec0d0b3 100644 --- a/R/mread.R +++ b/R/mread.R @@ -283,8 +283,7 @@ mread <- function(model, project = getOption("mrgsolve.project", getwd()), unlist(labels(sigma)), .eta, .eps, - mread.env[["move_global"]], - mread.env[["defines"]] + build[["cpp_variables"]][["var"]] ) unique(ans) } diff --git a/inst/maintenance/unit/test-capture.R b/inst/maintenance/unit/test-capture.R index 618fca69..855fb7c0 100644 --- a/inst/maintenance/unit/test-capture.R +++ b/inst/maintenance/unit/test-capture.R @@ -52,6 +52,8 @@ test_that("error if cmt in capture issue-555", { code <- ' $PARAM CL=1, V2=20,Q=30,V3=200,KA=1 +$GLOBAL +double z = 5; $MAIN double b = 2; $OMEGA 1 $OMEGA @labels OGA2 @@ -60,15 +62,15 @@ $CAPTURE CL VP = V2 ' test_that("capture via mread", { - mod <- mcode("capture-mread", code, capture = "Q,a=b,OGA2") + mod <- mcode("capture-mread", code, capture = "Q,a=b,OGA2,z") out <- outvars(mod) - expect_equal(out$capture, c("CL", "VP", "Q", "a", "OGA2")) + expect_equal(out$capture, c("CL", "VP", "Q", "a", "OGA2", "z")) expect_error( - mread("pk1",modlib(),capture = "mrgsolve"), + mread("pk1", modlib(), capture = "mrgsolve"), msg = "all requested `capture` variables must exist in the model" ) - mod <- mcode("capture-mread", code, capture="(everything)", compile=FALSE) - res <- c("CL","VP", "Q", "V3", "KA", "OGA2", "ETA_1", "ETA_2", "b") + mod <- mcode("capture-mread", code, capture="(everything)", compile = FALSE) + res <- c("CL","VP", "Q", "V3", "KA", "OGA2", "ETA_1", "ETA_2", "z", "b") expect_equal(outvars(mod)$capture, res) }) From 1588dfd79fd99a1046bdfd6d5e5931fed7b94f68 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Sat, 4 Sep 2021 09:18:18 -0500 Subject: [PATCH 28/31] re-factor cpp_variables --- R/mread.R | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/R/mread.R b/R/mread.R index 4ec0d0b3..90fd0c50 100644 --- a/R/mread.R +++ b/R/mread.R @@ -277,13 +277,17 @@ mread <- function(model, project = getOption("mrgsolve.project", getwd()), } else { .eps <- NULL } + cppv <- NULL + if(is.data.frame(build[["cpp_variables"]])) { + cppv <- build[["cpp_variables"]][["var"]] + } ans <- c( names(param), unlist(labels(omega)), unlist(labels(sigma)), .eta, .eps, - build[["cpp_variables"]][["var"]] + cppv ) unique(ans) } From 08bde8de1fe0e1dd62e1ba5b40a6b7064d3bf4dc Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Sat, 4 Sep 2021 11:22:56 -0500 Subject: [PATCH 29/31] sort pp directive capture test --- inst/maintenance/unit/test-capture.R | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/inst/maintenance/unit/test-capture.R b/inst/maintenance/unit/test-capture.R index 855fb7c0..138dccb8 100644 --- a/inst/maintenance/unit/test-capture.R +++ b/inst/maintenance/unit/test-capture.R @@ -76,6 +76,5 @@ test_that("capture via mread", { test_that("capture pp directive via mread", { mod <- modlib("irm3", capture = "STIM", compile = FALSE) - expect_equal(outvars(mod)$capture, c("CP", "STIM")) + expect_equal(sort(outvars(mod)$capture), sort(c("CP", "STIM"))) }) - From d2b155b27ef9bba8d703d4ca722a392c6dafe696 Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Sat, 4 Sep 2021 12:07:50 -0500 Subject: [PATCH 30/31] stringsAsFactors ... again --- R/modspec.R | 9 +++++++-- R/mread.R | 6 +----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/R/modspec.R b/R/modspec.R index fde6b472..fd9e774a 100644 --- a/R/modspec.R +++ b/R/modspec.R @@ -328,7 +328,7 @@ get_c_vars2 <- function(y,context) { if(length(regm)==0) return(data.frame()) vars <- gsub(pattern="\\s*=$", replacement = "", x = regm, perl=TRUE) vars <- token_space(vars) - ans <- as.data.frame(do.call(rbind,vars),stringsAsFactors = FALSE) + ans <- as.data.frame(do.call(rbind,vars), stringsAsFactors = FALSE) names(ans) <- c("type", "var") if(nrow(ans) > 0) ans$context <- context ans @@ -354,7 +354,12 @@ pp_defs <- function(x,context) { code <- s_pick(x, 3) list( vars = vars, code = code, n = length(x), - tab = data.frame(type = "define", var = vars, context = "global") + tab = data.frame( + type = "define", + var = vars, + context = "global", + stringsAsFactors = FALSE + ) ) } diff --git a/R/mread.R b/R/mread.R index 90fd0c50..4ec0d0b3 100644 --- a/R/mread.R +++ b/R/mread.R @@ -277,17 +277,13 @@ mread <- function(model, project = getOption("mrgsolve.project", getwd()), } else { .eps <- NULL } - cppv <- NULL - if(is.data.frame(build[["cpp_variables"]])) { - cppv <- build[["cpp_variables"]][["var"]] - } ans <- c( names(param), unlist(labels(omega)), unlist(labels(sigma)), .eta, .eps, - cppv + build[["cpp_variables"]][["var"]] ) unique(ans) } From 9bad8adaad2d4c3c72e6ceccdd98c636b38101bd Mon Sep 17 00:00:00 2001 From: Kyle Baron Date: Sat, 4 Sep 2021 12:09:57 -0500 Subject: [PATCH 31/31] remove sorting in test --- inst/maintenance/unit/test-capture.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/maintenance/unit/test-capture.R b/inst/maintenance/unit/test-capture.R index 138dccb8..91489619 100644 --- a/inst/maintenance/unit/test-capture.R +++ b/inst/maintenance/unit/test-capture.R @@ -76,5 +76,5 @@ test_that("capture via mread", { test_that("capture pp directive via mread", { mod <- modlib("irm3", capture = "STIM", compile = FALSE) - expect_equal(sort(outvars(mod)$capture), sort(c("CP", "STIM"))) + expect_equal(outvars(mod)$capture, c("CP", "STIM")) })