GithubHelp home page GithubHelp logo

nlmixr2 / babelmixr2 Goto Github PK

View Code? Open in Web Editor NEW
6.0 6.0 1.0 15.79 MB

The goal of babelmixr2 is to convert nlmixr2 syntax to other commonly used tools

Home Page: https://nlmixr2.github.io/babelmixr2/

R 96.12% C++ 3.64% C 0.18% Shell 0.06%
monolix nonmem pharmacometrics r

babelmixr2's Introduction

nlmixr2

Cran updating status R-CMD-check Codecov test coverage CodeFactor CRAN version CRAN total downloads CRAN total downloads

The vision of nlmixr2 is to develop a R-based open-source nonlinear mixed-effects modeling software package that can compete with commercial pharmacometric tools and is suitable for regulatory submissions.

In short, the goal of nlmixr2 is to support easy and robust nonlinear mixed effects models in R. This is supported by our team and advisory committee

Blog for more information

For more information about ongoing development, best practices, and news about nlmixr2, please see the nlmixr2 blog.

Installation

For all versions of R, we need to have a compiler setup to run nlmixr2 and rxode2

Windows compilation tools setup

For Windows the compilers come from RTools. Download and the install the version of RTools for your version of R from https://cran.r-project.org/bin/windows/Rtools/

Mac compilation tools setup

To setup the mac compilers, simply

  1. Install Xcode from app store

  2. Install gfortran:

    1. Download and install from https://mac.r-project.org/tools/

    2. Add gfortran directory to the path with: export PATH=$PATH:/usr/local/gfortran/bin

R package installation

Installation nlmixr2 itself is easiest the latest version of R because no further compilation is required and all supporting packages are available. From R, run:

install.packages("nlmixr2",dependencies = TRUE)

For R-4.0.x and R-4.1.x, the symengine package will need to be downgraded to run in those earlier R versions. This can be done by:

# install.packages("remotes")
remotes::install_version("symengine", version = "0.1.6")

followed by:

install.packages("nlmixr2",dependencies = TRUE)

Checking installation

You can check that your installation is likely setup correctly with the following command after installing the nlmixr2 package:

nlmixr2::nlmixr2CheckInstall()

Development version installation

Once the compilers are setup and a compatible version of symengine is installed, you can install the development version of nlmixr2 and its nlmixr2-family dependencies either by using the r-universe or by installing manually.

Install using the R universe

For many people this is the fastest way to install the development version of nlmixr2 since it provides binaries for mac, windows for the latest and last version of R (no need to wait for a compile).

install.packages(c("dparser", "nlmixr2data", "lotri", "rxode2ll",
                   "rxode2parse", "rxode2random", "rxode2et",
                   "rxode2", "nlmixr2est", "nlmixr2extra", "nlmixr2plot",
                   "nlmixr2"),
                 repos = c('https://nlmixr2.r-universe.dev',
                           'https://cloud.r-project.org'))

If you are using a Ubuntu latest flavor (at the time of this writing jammy) you can also use the binaries (though if you use bspm you should install any dependencies first to reduce your computation time)

# bspm::disable() # if you are using r2u or other ubuntu binary for CRAN
oldOptions <- options()

options(repos=c(
  linux = 'https://nlmixr2.r-universe.dev/bin/linux/jammy/4.2/',
  sources = 'https://nlmixr2.r-universe.dev',
  cran = 'https://cloud.r-project.org'
))
install.packages(c("dparser", "nlmixr2data", "lotri", "rxode2ll",
                   "rxode2parse", "rxode2random", "rxode2et",
                   "rxode2", "nlmixr2est", "nlmixr2extra", "nlmixr2plot",
                   "nlmixr2"))

options(oldOptions)
#bspm::enable()

Support packages from the R universe can also be installed for the packages in the nlmixr2 domain:

install.packages(c("xpose.nlmixr2", # Additional goodness of fit plots
                                    # baesd on xpose
                   "nlmixr2targets", # Simplify work with the
                                     # `targets` package
                   "babelmixr2", # Convert/run from nlmixr2-based
                                 # models to NONMEM, Monolix, and
                                 # initialize models with PKNCA
                   "nonmem2rx", # Convert from NONMEM to
                                # rxode2/nlmixr2-based models
                   "nlmixr2lib", # a model library and model
                                 # modification functions that
                                 # complement model piping
                   "nlmixr2rpt" # Automated Microsoft Word and
                                # PowerPoint reporting for nlmixr2
                   ),
                 repos = c('https://nlmixr2.r-universe.dev',
                           'https://cloud.r-project.org'))

# Some additional packages outside of the `nlmixr2.r-univers.dev`
# install.packages("remotes")
remotes::install_github("ggPMXdevelopment/ggPMX") # Goodness of fit plots
remotes::install_github("RichardHooijmaijers/shinyMixR") # Shiny run manager (like Piranha)

For Ubuntu latest it is similar

# bspm::disable() # if you are using r2u or other ubuntu binary for CRAN
oldOptions <- options()

options(repos=c(
  linux = 'https://nlmixr2.r-universe.dev/bin/linux/jammy/4.2/',
  sources = 'https://nlmixr2.r-universe.dev',
  cran = 'https://cloud.r-project.org'
))
install.packages(c("xpose.nlmixr2", "nlmixr2targets", "babelmixr2", "nonmem2rx", "nlmixr2lib", "nlmixr2rpt"))

options(oldOptions)
#bspm::enable()
# install.packages("remotes")
remotes::install_github("ggPMXdevelopment/ggPMX") # Goodness of fit plots
remotes::install_github("RichardHooijmaijers/shinyMixR") # Shiny run manager (like Piranha)

Install using remotes

This is sure to give the latest development version

# install.packages("remotes")
remotes::install_github("nlmixr2/dparser-R")
remotes::install_github("nlmixr2/nlmixr2data")
remotes::install_github("nlmixr2/lotri")
remotes::install_github("nlmixr2/rxode2ll")
remotes::install_github("nlmixr2/rxode2parse")
remotes::install_github("nlmixr2/rxode2random")
remotes::install_github("nlmixr2/rxode2et")
remotes::install_github("nlmixr2/rxode2")
remotes::install_github("nlmixr2/nlmixr2est")
remotes::install_github("nlmixr2/nlmixr2extra")
remotes::install_github("nlmixr2/nlmixr2plot")
remotes::install_github("nlmixr2/nlmixr2")

Optional supporting packages can be installed like so:

# install.packages("remotes")
# Goodness of fit plots
remotes::install_github("ggPMXdevelopment/ggPMX")
# Additional goodness of fit plots
remotes::install_github("nlmixr2/xpose.nlmixr2")
# Shiny run manager (like Piranha)
remotes::install_github("RichardHooijmaijers/shinyMixR")
# Simplify work with the `targets` package
remotes::install_github("nlmixr2/nlmixr2targets")
# Convert/run from nlmixr2-based models to NONMEM, Monolix, and initialize
# models with PKNCA
remotes::install_github("nlmixr2/babelmixr2")
# Convert from NONMEM to rxode2/nlmixr2-based models
remotes::install_github("nlmixr2/nonmem2rx")
# A library of models and model modification functions
remotes::install_github("nlmixr2/nlmixr2lib")
# Automated Microsoft Word and PowerPoint reporting for nlmixr2
remotes::install_github("nlmixr2/nlmixr2rpt")

Refreshing the installation with the latest CRAN version

If you have difficulties due to errors while compiling models, it may be useful to re-install all of nlmixr2 and its dependencies. For development versions, please use the remotes::install_github() or the install.package() with the r-universe above. For the stable version, please use the following command:

install.packages(c("dparser", "lotri", "rxode2ll", "rxode2parse",
                   "rxode2random", "rxode2et", "rxode2",
                   "nlmixr2data", "nlmixr2est", "nlmixr2extra",
                   "nlmixr2plot", "nlmixr2"))

Example

This is a basic example which shows you how to solve a common problem:

library(nlmixr2)

## The basic model consists of an ini block that has initial estimates
one.compartment <- function() {
  ini({
    tka <- log(1.57); label("Ka")
    tcl <- log(2.72); label("Cl")
    tv <- log(31.5); label("V")
    eta.ka ~ 0.6
    eta.cl ~ 0.3
    eta.v ~ 0.1
    add.sd <- 0.7
  })
  # and a model block with the error specification and model specification
  model({
    ka <- exp(tka + eta.ka)
    cl <- exp(tcl + eta.cl)
    v <- exp(tv + eta.v)
    d/dt(depot) <- -ka * depot
    d/dt(center) <- ka * depot - cl / v * center
    cp <- center / v
    cp ~ add(add.sd)
  })
}

## The fit is performed by the function nlmixr/nlmixr2 specifying the model, data and estimate
fit <- nlmixr2(one.compartment, theo_sd,  est="saem", saemControl(print=0))
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00 
#> 
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00 
#> 
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00 
#> 
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00 
#> 
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00 
#> 
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00 
#> 
#> [====|====|====|====|====|====|====|====|====|====] 0:00:00
print(fit)
#> ── nlmixr² SAEM OBJF by FOCEi approximation ──
#> 
#>  Gaussian/Laplacian Likelihoods: AIC() or $objf etc. 
#>  FOCEi CWRES & Likelihoods: addCwres() 
#> 
#> ── Time (sec $time): ──
#> 
#>            setup covariance  saem table compress    other
#> elapsed 0.000891   0.020004 2.792 0.043    0.017 2.397105
#> 
#> ── Population Parameters ($parFixed or $parFixedDf): ──
#> 
#>        Parameter  Est.     SE %RSE Back-transformed(95%CI) BSV(CV%) Shrink(SD)%
#> tka           Ka  0.46  0.196 42.7       1.58 (1.08, 2.33)     71.9    -0.291% 
#> tcl           Cl  1.01 0.0839 8.29       2.75 (2.34, 3.25)     27.0      3.42% 
#> tv             V  3.45 0.0469 1.36       31.6 (28.8, 34.7)     14.0      10.7% 
#> add.sd           0.694                               0.694                     
#>  
#>   Covariance Type ($covMethod): linFim
#>   No correlations in between subject variability (BSV) matrix
#>   Full BSV covariance ($omega) or correlation ($omegaR; diagonals=SDs) 
#>   Distribution stats (mean/skewness/kurtosis/p-value) available in $shrink 
#>   Censoring ($censInformation): No censoring
#> 
#> ── Fit Data (object is a modified tibble): ──
#> # A tibble: 132 × 19
#>   ID     TIME    DV  PRED    RES IPRED   IRES  IWRES eta.ka eta.cl   eta.v    cp
#>   <fct> <dbl> <dbl> <dbl>  <dbl> <dbl>  <dbl>  <dbl>  <dbl>  <dbl>   <dbl> <dbl>
#> 1 1      0     0.74  0     0.74   0     0.74   1.07  0.0988 -0.484 -0.0843  0   
#> 2 1      0.25  2.84  3.27 -0.433  3.87 -1.03  -1.49  0.0988 -0.484 -0.0843  3.87
#> 3 1      0.57  6.57  5.85  0.718  6.82 -0.247 -0.356 0.0988 -0.484 -0.0843  6.82
#> # ℹ 129 more rows
#> # ℹ 7 more variables: depot <dbl>, center <dbl>, ka <dbl>, cl <dbl>, v <dbl>,
#> #   tad <dbl>, dosenum <dbl>

Plotting outputs

Base R Graphics

You can use the built-in plot with the fit and it will produce a standard set of goodness of fit plots:

pdf(file="myplots.pdf")
plot(fit)
dev.off()

xpose.nlmixr2

The {xpose.nlmixr2} package extends xpose support for nlmixr2. You simply need to convert the fit results into an xpose database:

library(xpose.nlmixr2)
xpdb = xpose_data_nlmixr(fit)

Then you can use any of the xpose functions for generating goodness of fit plots:

library(xpose)
plt <- dv_vs_ipred(xpdb)

ggPMX

Another option is to use the ggPMX package. You first create a ggPMX controller object from the nlmixr fit object. Then that controller object can be used to generate figures:

library(ggPMX)
ctr = pmx_nlmixr(fit)
pmx_plot_dv_ipred(ctr)

babelmixr2's People

Contributors

billdenney avatar mattfidler avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

babelmixr2's Issues

Nested if/else not supported for nmtran

pk.turnover.emax3.nmctl pk.turnover.emax3.lst
Starting NMTRAN

AN ERROR WAS FOUND IN THE CONTROL STATEMENTS.

AN ERROR WAS FOUND ON LINE 117 AT THE APPROXIMATE POSITION NOTED:
END IF
X
326 RANDOM VARIABLE IS DEFINED IN A NESTED IF STRUCTURE.

Test correction question

I was trying to fix the tests for NONMEM, and I got an error that p$nonmemErr is NULL. It appears that this may have changed to p$nonmemErrF and that the format may have changed. Is that correct?

(I'm working through many updates to the tests, so no need to change this as I'll make the update in conjunction with other test changes that I'm making.)

expect_equal(p$nonmemErr,

Feature request: Data cleaner and standardization functions

I know that nlmixr2 (and I think that it's mainly in rxode2) does data cleaning before the model is sent to the integrator. I don't know where this is done, overall. And, I think that there would be additional needs within nlmixr2est. I think that it would be helpful to simplify, standardize, and centralize this data cleaning.

Related to #45

`ipred`

  • ipred
AN ERROR WAS FOUND ON LINE 54 AT THE APPROXIMATE POSITION NOTED:
   IPRED = A(7);RX_PRED_F_
   X                      
 THE CHARACTERS IN ERROR ARE: IPRED                         
  292  THIS VARIABLE NAME IS GLOBAL AND MAY NOT BE RE-DEFINED.

Random variable may not be redefined in the same the or else block

pk.turnover.emax3.nmctl pk.turnover.emax3.lst
Starting NMTRAN
 
 AN ERROR WAS FOUND IN THE CONTROL STATEMENTS.
 
AN ERROR WAS FOUND ON LINE 39 AT THE APPROXIMATE POSITION NOTED:
     RXDZ001= -0.000001
     X                 
 THE CHARACTERS IN ERROR ARE: RXDZ00
  469  RANDOM VARIABLE MAY NOT BE REDEFINED IN SAME "THEN" OR "ELSE" BLOCK.

How is genRxControl used?

I'm trying to document nonmemControl(), but I'm not sure the purpose of the only allowed ... argument of genRxControl. Why isn't it inferred from the rxControl argument (or a simpler named argument)?

if (runCommand != "") checkmate::assertCharacter(runCommand, pattern="%s", min.len=1, max.len=1)
.xtra <- list(...)
.bad <- names(.xtra)
.bad <- .bad[!(.bad %in% c("genRxControl"))]

What is the purpose of `.nonmemSetCmtProperty()`?

In this code, why is .nonmemSetCmtProperty() needed rather than directly generating the code for things like lag time and bioavailability?

babelmixr2/R/nonmem.R

Lines 547 to 614 in 5adebcf

.rxToNonmemHandleAssignmentOperator <- function(x, ui) {
if (length(x[[2]]) == 2L) {
if (identical(x[[2]][[2]], 0)) {
.state <- as.character(x[[2]][[1]])
#if (length(x[[3]]) == 1L) {
rxode2::rxAssignControlValue(ui, ".ifelse", TRUE)
on.exit(rxode2::rxAssignControlValue(ui, ".ifelse", FALSE))
.extra <- .rxToNonmem(x[[3]], ui=ui)
.nonmemSetCmtProperty(ui, .state, .extra, type="init")
return(paste0(.rxToNonmemGetIndent(ui),
paste0(";", as.character(x[[2]])[1], "(0) defined in $PK block")))
}
if (any(as.character(x[[2]])[1] == c("alag", "lag", "F", "f", "rate", "dur"))) {
# I believe these have to be in the $PK block
if (any(as.character(x[[2]])[1] == c("alag", "lag"))) {
.state <- as.character(x[[2]][[2]])
if (length(x[[3]]) == 1L) {
.extra <- .rxToNonmem(x[[3]], ui=ui)
.nonmemSetCmtProperty(ui, .state, .extra, type="lag")
} else {
stop("the complex lag time is not supported by babelmixr2",
call.=FALSE)
}
}
if (any(as.character(x[[2]])[1] == c("F", "f"))) {
.state <- as.character(x[[2]][[2]])
if (length(x[[3]]) == 1L) {
.extra <- .rxToNonmem(x[[3]], ui=ui)
.nonmemSetCmtProperty(ui, .state, .extra, type="f")
} else {
stop("the complex F is not supported by babelmixr2",
call.=FALSE)
}
}
if (as.character(x[[2]])[1] == "rate") {
.state <- as.character(x[[2]][[2]])
if (length(x[[3]]) == 1L) {
.extra <- .rxToNonmem(x[[3]], ui=ui)
.nonmemSetCmtProperty(ui, .state, .extra, type="rate")
} else {
stop("the complex rate is not supported by babelmixr2",
call.=FALSE)
}
}
if (as.character(x[[2]])[1] == "dur") {
.state <- as.character(x[[2]][[2]])
if (length(x[[3]]) == 1L) {
.extra <- .rxToNonmem(x[[3]], ui=ui)
.nonmemSetCmtProperty(ui, .state, .extra, type="dur")
} else {
stop("the complex dur is not supported by babelmixr2",
call.=FALSE)
}
}
return(paste0(.rxToNonmemGetIndent(ui),
";", as.character(x[[2]])[1], " defined in $PK block"))
}
}
.var <- .rxToNonmem(x[[2]], ui=ui)
.val <- .rxToNonmem(x[[3]], ui=ui)
.prefixLines <- rxode2::rxGetControl(ui, ".nmPrefixLines", NULL)
.extra <- ""
if (!is.null(.prefixLines)) {
.extra <- paste0(paste(.prefixLines, collapse="\n"), "\n")
rxode2::rxAssignControlValue(ui, ".nmPrefixLines", NULL)
}
return(paste0(.extra, .rxToNonmemGetIndent(ui), .var, "=", .val))
}

May be wrong

 (WARNING  3) THERE MAY BE AN ERROR IN THE ABBREVIATED CODE. THE FOLLOWING
 ONE OR MORE RANDOM VARIABLES ARE DEFINED WITH "IF" STATEMENTS THAT DO NOT
 PROVIDE DEFINITIONS FOR BOTH THE "THEN" AND "ELSE" CASES. IF ALL
 CONDITIONS FAIL, THE VALUES OF THESE VARIABLES WILL BE ZERO.
  
   RX_PRED_F_ IPRED RX_PRED_ W

Question: How do I create a new estimation method?

I want to create a new estimation method that will give initial estimates for nlmixr2 using noncompartmental parameters from PKNCA.

For that, I know that I'll need to add some of the parts that are similar to what has been done for NONMEM and Monolix, but it will also likely be simpler than those since it can stay fully within R. I think that the main parts are the following, but I'd like to confirm:

  • Create a pkncaControl() function with all needed control parameters.
  • Create a nlmixr2Est.pknca() function that will initialize the UI object with any PKNCA-specific parts, perform the actual calculations, and update the UI object with the results.

I think that those are the only two required parts. Is that correct?

If yes, my plan is to make nlmixr2Est.pknca() change the initial estimates using the ini() function or possibly going directly to the ui$iniDf. Do you see any issues with doing that? Is one of ini() or ui$iniDf preferred?

And finally, I was planning to determine the correct model parameter and transformation from the ui$iniDf data.frame. The idea was to look for either ka or lka to find absorption rate and determine if it should be log-transformed or not, for example. I looked at ui$iniDf, and the backTransform column was all NA in a model that estimated log-transformed parameters. Is there a better way to detect the transform used for a parameter than the heuristic of looking for an "l" at the beginning for log transform?

Feature Request: Simplify reading NONMEM results

I have babelmixr2 successfully running a remote NONMEM using the function interface to copy the files to the remote system, run NONMEM, and pull the files back.

When the files get back, there are issues loading the results. I'm trying to work through them, but I think that I'd prefer to rework the way that NONMEM results are loaded a bit so that it works more like:

  1. Load all the files and store them at appropriate locations within the UI object. For example, store them as "nonmemXML", "nonmemCov", "nonmemExt", "nonmemSdtab", and "nonmemPatab" or something like those (there may be a few more). And, I'd like to do all of that in a single function like "rxUiGet.nonmemLoad()"
  2. After that, don't look at the files anymore.
  3. Update the NONMEM -> nlmixr2 information pull to use the new structures.

Any issues with that? Anything that I'm missing where the way it's working is important for general nlmixr2 operation?

Add URLs

They are missing in the description

More Advanced Feature Request: Only zero-protect values that need it

I just generated a model using the following code, and it unnecessarily zero-protected V in the $DES block. It could have known that V is positive because it's exponentiated in the $PK block.

one.cmt <- function() {
    ini({
      tka <- 0.45 ; label("Ka")
      tcl <- log(c(0, 2.7, 100)) ; label("Log Cl")
      tv <- 3.45; label("log V")
      eta.ka ~ 0.6
      eta.cl ~ 0.3
      eta.v ~ 0.1
      add.sd <- 0.7
    })
    model({
      ka <- exp(tka + eta.ka)
      cl <- exp(tcl + eta.cl)
      v <- exp(tv + eta.v)
      d/dt(depot) <- -ka * depot
      d/dt(central) <- ka * depot - cl/v * central
      cp <- central / v
      cp ~ add(add.sd)
    })
  }
  
  ui <- nlmixr(one.cmt, data=nlmixr2data::Oral_1CPT, est="nonmem")

The generated NONMEM model has the following where the RXDZ001 protection of V is unnecessary.

$PK
  MU_1=THETA(1)
  MU_2=THETA(2)
  MU_3=THETA(3)
  KA=DEXP(MU_1+ETA(1)) ; ka <- exp(tka)
  CL=DEXP(MU_2+ETA(2)) ; cl <- exp(tcl)
  V=DEXP(MU_3+ETA(3)) ; v <- exp(tv)

$DES
  DADT(1) = - KA*A(1) ; d/dt(depot) = -ka * depot
  RXDZ001=V
  IF (RXDZ001 .GE. 0.0 .AND. RXDZ001 .LE. 0.000001) THEN
    RXDZ001=0.000001
  END IF
  IF (RXDZ001 .GE. -0.000001 .AND. RXDZ001 .LT. 0.) THEN
    RXDZ001= -0.000001
  END IF
  DADT(2) = KA*A(1)-CL/RXDZ001*A(2) ; d/dt(central) = ka * depot - cl/v * central
  CP=A(2)/RXDZ001 ; cp = central/v

Invalid `.cov` subscripts for Monolix

When running this test:

if (file.exists("pk.turnover.emax3-2019.zip")) {
.path <- normalizePath("pk.turnover.emax3-2019.zip")
withr::with_tempdir({
unzip(.path)
f <- nlmixr2::nlmixr(pk.turnover.emax3, nlmixr2data::warfarin, "monolix")
expect_true(inherits(f, "nlmixr2FitData"))
})
}

I get this error:

Error in .cov[.n, .n] : subscript out of bounds
Error: subscript out of bounds

It comes from here:

.n <- vapply(dimnames(.j)[[1]], function(n){
paste0(.muRef[n], "_pop")
}, character(1), USE.NAMES=FALSE)
.cov <- .cov[.n, .n]

The issue is that .muRef is NULL which comes from the fact that x$getSplitMuModel is NULL just above that.

I don't readily see where x$getSplitMuModel is supposed to come from.

Need to use DVID instead of cmt

0DATA REC    2: COMPARTMENT ASSOCIATED WITH THE PREDICTION IS OFF: CMT=    5
0DATA REC    3: COMPARTMENT ASSOCIATED WITH THE PREDICTION IS OFF: CMT=    5
0DATA REC    4: COMPARTMENT ASSOCIATED WITH THE PREDICTION IS OFF: CMT=    5
0DATA REC    5: COMPARTMENT ASSOCIATED WITH THE PREDICTION IS OFF: CMT=    5
0DATA REC    6: COMPARTMENT ASSOCIATED WITH THE PREDICTION IS OFF: CMT=    5
0DATA REC    7: COMPARTMENT ASSOCIATED WITH THE PREDICTION IS OFF: CMT=    5
0DATA REC    8: COMPARTMENT ASSOCIATED WITH THE PREDICTION IS OFF: CMT=    5
0DATA REC    9: COMPARTMENT ASSOCIATED WITH THE PREDICTION IS OFF: CMT=    5
0DATA REC   10: COMPARTMENT NUMBER IS INAPPROPRIATE FOR THIS MODEL

Use `system2()` instead of `system()`?

Using system() will likely result in issues with spaces in filenames and parsing of arguments. system2() has the complexity that it requires using a vector of command line arguments instead of a simpler string. This issue is mainly for consideration rather than trying to push hard for system2()-- it's more of a gentle nudge.

system(sprintf(.cmd, .arg)))

The same would apply for Monolix:

system(sprintf(.cmd, .mlxtran))

regressor not present in pbpk.txt

[monolix] ERROR : The given file : "/home/fidlema3/babelmixr2/pbpk.mlxtran" cannot be properly loaded :
Parse error in '/home/fidlema3/babelmixr2/pbpk.mlxtran', 
line 32:
Parse error in '/home/fidlema3/babelmixr2/pbpk.txt', 
line 14:
Undefined variable "WT".

$DES issue

 AN ERROR WAS FOUND IN THE CONTROL STATEMENTS.
 
AN ERROR WAS FOUND ON LINE 55 AT THE APPROXIMATE POSITION NOTED:
   IPRED = RX_PRED_F_
   X                 
 THE CHARACTERS IN ERROR ARE: RX_PRED_F_                    
  446  VARIABLE DEFINED IN $DES MUST BE REDEFINED WITH NEW NAME IN $ERROR.

Invalid NONMEM XML file causes error

In a recent test run, NONMEM completed the run successfully, but the xml file was truncated. In this case, should we try another method to load one of the other output files?

Should this be fixed here or in pmxTools?

NONMEM protectZeros issues

While reviewing the tests for NONMEM, I see one feature request and one issue with protectZeros:

  • Issue: Negative values would be caught with the protectZeros protection. I.e. if a value is -1, it would not divide by -1, but it would divide by 0.000001.
  • Feature request: It appears that when protectZeros=TRUE, the protection value is always 0.000001. I think it would be preferable to set it to 0 not to protect zeros and then nonzero (e.g. protectZeros=0.000001) to set the value that should be used.

To resolve the issue, I think that we may need to check if X .LE. 0.000001 .AND. X .GE. -0.000001. When a modeler adds that protection manually, they are aware if .LE. is the only needed summary vs .LE. .AND. .GE.. I think that we need to think about how that manual protection could be added.

Question/Feature Request: How is a user notified of the reason for NONMEM run failure?

There are many ways that NONMEM may fail to run via babelmixr2. Off the top of my head, some options are:

  1. The runCommand is not given correctly (a babelmixr2 setup issue)
  2. The runCommand is not valid for the system where it is used (an information technology support issue)
  3. The NONMEM license file is not available or is expired
  4. There is a control stream error (a babelmixr2 error in converting the model to NONMEM)
  5. There is a dataset error (likely a babelmixr2 error in making the dataset NONMEM-ready; maybe a NONMEM error; ref #42)
  6. NONMEM crashes in some way during estimation (a NONMEM error that we need to be able to tell the user about)
  7. babelmixr2 (and therefore pmxTools under the surface) cannot read the NONMEM output.

There are probably more ways that I'm not thinking of.

It seems like there should be a way to tell the user when these things happen. I don't know that we have to cover all of these separately (for example, 1 and 2 are very similar and not likely to be distinguishable from the perspective of babelmixr2). But, we will get lots of questions or bug reports if we don't have clear errors pointing users to where the error is and a potential fix.

Currently, I don't think that we give clear error messages to the user about these things.

`csv`

The nonmem csv needs the header row not to have quotes

`RX001`

Starting NMTRAN
 
 AN ERROR WAS FOUND IN THE CONTROL STATEMENTS.
 
AN ERROR WAS FOUND ON LINE 57 AT THE APPROXIMATE POSITION NOTED:
   RX001=204
   X        
 THE CHARACTERS IN ERROR ARE: RX001                         
  292  THIS VARIABLE NAME IS GLOBAL AND MAY NOT BE RE-DEFINED.

Use NONMEM's `PROTECT` feature

Apparently there is an undocumented or poorly document feature in NONMEM called PROTECT that also protects from divide by zeros. Someone said it was supported in 7.4, so at least add an option and possibly turn it on by default

Missing files for NONMEM tests

The files for testing NONMEM in tests/testthtat/test-nonmem-read.R are not present in the tests/testthat/ directory (or in the repository at all, that I see).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.