Available as of mrgsolve version 1.0.0.
When this plugin is invoked, mrgsolve will search your model code for assignments
and automatically declare them as
double precision numbers. The following
blocks are searched
For example, the following code requires that
CL gets assigned a type
= 70, TVCL = 1.2 $PARAM WT $PKdouble CL = TVCL * pow(WT/70, 0.75);
This is the default mrgsolve behavior and has been since the beginning.
autodec plugin lets you write the following
$PLUGIN autodec = 70, TVCL = 1.2 $PARAM WT $PK= TVCL * pow(WT/70, 0.75);CL
mrgsolve will find
CL = ... and understand that this is a user initiated
variable and will declare it as
double for you. Don’t worry about
WT = 70
$PARAM; mrgsolve should already know about that won’t try to declare it.
When you are using the
autodec plugin, you can still declare variables as
bool. mrgsolve already finds those variables and will
understand to leave those declarations alone. Note that it may still very
convenient to declare using the
capture type those variables that you
want captured into the output
$PLUGIN autodec $ERROR= IPRED * exp(EPS(1));capture Y
capture typedef makes
double; we didn’t need to declare it with
autodec in play, but decided to declare with
capture so that it is copied
into the simulated output.
autodec plugin is intended for more straightforward models where most /
all variables are real valued. Because mrgsolve can handle any valid C++ code
in these blocks, there is a possibility that the code could get much more
complicated, including custom classes and methods. In this case, we recommend
to bypass this feature and take control of declaring variables as you would
in the default mode.
In case mrgsolve does try to declare (as
double) a variable that shouldn’t
be handled that way, you can note this name in an environment variable inside
your model called
= c("my_variable_1")$ENV MRGSOLVE_AUTODEC_SKIP
This can be a vector of variable names to NOT declare when
autodec is invoked.
Available as of mrgsolve version 1.0.0.
nm-vars plugin provides a more NONMEM-like set of macros to use when
coding your compartmental model. Only a small subset of the NONMEM model syntax
is replicated here.
F, R, D, ALAG
- To set bioavailability for the nth compartment, use
- To set the infusion rate for the nth compartment, use
- To set the infusion duration for the nth compartment, use
- To set the lag time for the nth compartment, use
$CMT GUT CENT GUT2 $PK= 0.87; // equivalent to F_GUT = 0.87; F1 = 2.25; // equivalent to R_CENT = 2.25; R2 = 0.25; // equivalent to ALAG_GUT2 = 0.25; ALAG3
A, A_0, DADT
- To refer to the amount in the nth compartment, use
- To refer to the initial amount in the nth compartment, use
- To refer to the differential equation for the nth compartment, use
$CMT CMT1 CMT2 $PK(2) = 50; A_0 $DES(1) = -KA * A(1); DADT(2) = KA * A(1) - KE * A(2); DADT
Starting with version 1.0.1, macros are provided for several math functions
EXP(a)gets mapped to
LOG(a)gets mapped to
SQRT(a)gets mapped to
These are purely for convenience, so that upper-case versions from NMTRAN don’t require conversion to lower-case; this happens automatically via the C++ preprocessor.
THETA(n)in model code will resolve to
THETAn; this feature is always available, even when
nm-varshasn’t been invoked; we mention it here since it is a fundamental piece of the NONMEM syntax that mrgsolve has internalized
$DESto refer to the current time in the odesolver rather than
Reserved words with nm-vars is invoked
There are some additional reserved words when the
nm-vars plugin is invoked
It is an error to use one of these symbols as the name of a parameter or compartment or to try to declare them as variables.
mrgsolve syntax that is still required
There are a lot of differences remaining between mrgsolve and NONMEM syntax. We mention a few here to make the point
- mrgsolve continues to require
pow(base, exponent)rather than
- mrgsolve continues to require a semi-colon at the end of each statement (this is a C++ requirement)
- mrgsolve continues to require that user-defined variables are declared with
a type, except when the
autodecplugin (Section 9.1) is invoked
There is an example of this syntax (along with
autodec features) in the
internal model library
. . Model file: nm-like.cpp . $PROB Model written with some nonmem-like syntax features . . $PLUGIN nm-vars autodec . . $PARAM . THETA1 = 1, THETA2 = 21, THETA3 = 1.3, WT = 70, F1I = 0.5, D2I = 2 . KIN = 100, KOUT = 0.1, IC50 = 10, IMAX = 0.9 . . $CMT @number 3 . . $PK . CL = THETA(1) * pow(WT/70, 0.75); . V = THETA(2); . KA = THETA(3); . . F1 = F1I; . D2 = D2I; . A_0(3) = KIN / KOUT; . . $DES . CP = A(2)/V; . INH = IMAX*CP/(IC50 + CP); . . DADT(1) = -KA*A(1); . DADT(2) = KA*A(1) - (CL/V)*A(2); . DADT(3) = KIN * (1-INH) - KOUT * A(3); . . $ERROR . CP = A(2)/V;
Purpose Advanced calculation time after dose within your model. We call this “advanced” because it lets you track doses in multiple compartments. See the note below about a simpler way to calculate time after dose that should work fine if doses are only in a single compartment. This functionality is provided by mrgsolve.
mrgsolve that you want to use the
tadose objects, one for each compartment where you want to track
time after dose. One approach is to do this in
[ global ]
[plugin] tad [ global ] ::tadose tad_cmt_1(1); mrg::tadose tad_cmt_2(2);mrg
Notice that we pass the compartment number that we want to track in each
case and also that we refer to the
mrg:: namespace for the
tadose objects contain the following (public) members
cmtthe compartment to track
toldthe time of last dose; defaults to
had_doseindicates if a dose has already been given for the current individual
tad(self)the function to call to calculate time after dose
selfobject (Section 2.3.12) must be passed as the only argument
- when the member function is called prior to the first administered dose, a
reset()resets the state of the object; be sure to reset prior to simulating a new individual
As an example, you can call the
reset() method on one of the
You can find the source code for this object here.
A working example model that tracks doses in compartments
[plugin] tad [ global ] ::tadose tad_cmt_1(1); mrg::tadose tad_cmt_2(2); mrg [ pkmodel ] cmt = "GUT,CENT", depot = TRUE [ param ] CL = 1, V = 20, KA = 1 [ main ] = tad_cmt_1.tad(self); capture tad1 = tad_cmt_2.tad(self);capture tad2
Another approach would be to make these static in
[ main ] but this approach
would only work if you only use these in
[ main ]; the
[ global ] approach
is preferable since then you can access the object in any block (function).
Note there is a simpler way to calculate time after dose when only dosing into a single compartment
[ main ] double tad = self.tad();
self object (Section 2.3.20) contains a
tad() member which
will track time after dose. Note that this needs to be called every record.
Rcpp headers into your model.
Note that once your model is linked to
Rcpp, you can start using that
functionality immediately (without including
A very useful feature provided by
Rcpp is that it exposes all of the
functions that you normally use in R (e.g.
runif()). So, if you
want to simulate a number from Uniform (0,1) you can write
$PLUGIN Rcpp $TABLEdouble uni = R::runif(0,1);
Note that the arguments are the same as the R version (
there is no
n argument; you always only get one draw.
Rcpp can be found here: https://github.com/RcppCore/Rcpp
Compile in extra C++ / Rcpp functions that can be helpful to you
for more advanced model coding. The
mrgx plugin is dependent on the
The functions provided by
mrgx are in a namespace of the same name,
so to invoke these functions, you always prepend
Note that your model object (
mod) contains an R environment. For
. <environment: 0x7f7b166b4608>
The objects in this environment are created by a block called
in your model code (see Section 2.2.26);
To access this environment in your model, call
::Environment env = mrgx::get_envir(self);Rcpp
When you have an object created in
[ env ] <- rnorm(100)rand
You can extract this object with
[ preamble ] ::NumericVector draw = mrgx::get("rand", self);Rcpp
RcppArmadillo headers into your model.
boost headers into your model.
Note that once your model is linked to
boost), you will be able to
boost header file that you need. You have to include the header
file that contains the
boost function you want to use.