Abbreviated code
Abbreviated code follows a subset of Fortran language syntax within an NM-TRAN control
stream. A block of abbreviated code begins with control record $PRED, $PK, $ERROR, $DES,
$AES, $AESINITIAL, $TOL, $MIX, or $INFN, and ends with either
another record (that begins with "$"), or the end of the
control stream. The code blocks are case-insensitive (NM72).
Comments
Semicolon character ; marks the beginning of comments so that the
rest of the line is ignored.
Line continuation
Character & at the end of a line indicates continuation to the next line.
Types
Reals
User-defined real variables do not require declaration. Using a
non-reserved (see "Reserved variables" below) word automatically
declares it a (double precision) real variable. For example, TVCL
below is recoganized as a real variable.
|
|
Integers
Integers variables are declared by (see $ABBREVIATED DECLARE for details)
|
|
A special index integer declared by
|
|
must be used for indices of DOWHILE loops. See "Index" section below.
Real vectors
One-dimensional real vector can be defined using
|
|
Assignment
A user-defined variable can have a name of length 1-20 (length limit defined by constant SD in SIZES), consisting of letters (A-Z), numerals (0-9), understore (_), and beginning with a letter. It cannot be one of the reserved variable names or keywords (see "Reserved variables" below).
A user-defined variable A is given value B through assignment state A=B.
The right-hand (RHS) quantity B can be an expression of:
- previously defined quantities (see $ABBREVIATED);
- constants 1, e.g. 1, 1.1, 3E+1, 3E1, 3E01, 3E-1 3E-01, 3D+1, 3D1, 3D01, 3D-1, 3D-01;
- THETA, OMEGA, and SIGMA elements, e.g.
THETA(1),OMEGA(1,3),OMEGA(2,2)(equivalentlyOMEGA(2), for diagonal elements); - data items defined from the
$INPUTrecord; - ETA, EPS, and ERR, elements, assummed with mean 0 and covariance matrix specifed by OMEGA and SIGMA;
- operators:
+,-,*,/, and**(exponentiate); - parentheses
(); - Fortran functions:
LOG(natural log),LOG10,EXP,SQRT,SIN,COS,ABS,TAN,ASIN,ACOS,ATAN,INT,MIN,MAX,MOD; - NONMEM function:
PHI(cumulative distribution function); - NONMEM function:
GAMLN(logarithm of the gamma function) 2; - NONMEM function: RANDMT and RANDMTU that return a random variables (See Introduction to NONMEM 7 for details).
Variables assigned with ETA, EPS, or ERR expressions are random variables, so are the quantities defined in terms of them. If a fortran function includes random variable arguments, NONMEM automatically computes the partial derivatives of these variables with respective to ETA, EPS, and ERR. However, special cases require attention:
- The partial derivative of ABS(X) at X=0 is mathematically
undefined. NONMEM defines it as
dX/dETA(similar for EPS, and ERR). Similarly, NONMEM does not compute partial derivatives for functions that return discontinuous values, such INT, MOD, MIN, and MAX. If using them outside of a simulation block such that the function value affects the objective function value (OFV) may lead to erroneous estimation. If they are needed in the computations ofDADTin$DES, then the funcions should be used instead in the PK routine, and model event time (see also Model Time examples). - The cumulative distribution function
PHImay accept a random variable argument, but NONMEM does not compute partial derivatives for it. - NONMEM computes derivatives only when they are needed, thus not in
simulation block, initialization block, finalization block, or
PRED_IGNORE_DATAblock (see Code blocks below.)
In addition to user-defined variables, left-hand quantities A can
also be:
- VECTRA(n), VECTRB(n), VECTRC(n): they become elements of
pre-defined vectors VECTRA, VECTRB, VECTRC. If an variable
VECTRA(same forVECTRB,VECTRC, etc) is used without an index, it referrs to a different scalar variable. An index must be an integer constant, or a character string that is replaced by an integer constant using the$ABBR REPLACEfeature. Whereas once it is defined, a vector element may be used as a right-hand quantity – in the same way as any previously defined variable – the vector itself may be used only as an argument to an abbreviated function. (See VECTORS and ABBREVIATED FUNCTIONS, below.) - Certain special variables: RPTO, RPTON and PRDFL - with the repetition feature (See Repetition Variables); SKIP_ (but only in a finalization block) - with superproblems or subproblems (See SKIP).
COM()elements. (COMis a storage array in module NMPRD4. Even if assigned with a random variables, NONMEM does not compute derivatives ofCOM()elements with respect to the base random variables).
In simulation blocks, initialization blocks, finalization blocks, a label
from $INPUT record can be on the left in an assignment statement.
See also pseudo-assignment below.
Loop (DO-WHILE)
DO-WHILE may be used in all blocks of abbreviated
code (NM73):
|
|
When it is used in data-anlytic code, DOWHILE must be used with a
looping counter defined with $ABBR DECLARE DOWHILE, as the ILOOP in
the example.
- DOWHILE blocks may be nested.
- DOWHILE blocks may not include IF/THEN/ENDIF blocks. Only single-statement IF statements are permitted.
-
Index variables may be used within the block. These are variables that have been declared arrays using the
$ABBRstatement, or indexed reserved variables such as THETA. Indices may be integer expressions using declared integer variables and integer values, e.g.1 2 3 4 5 6 7 8 9$ABBR DECLARE X(10) $ABBR DECLARE DOWHILE ILOOP ... $PK ILOOP=1 DOWHILE (condition) X(ILOOP)=THETA(ILOOP+1) ILOOP=ILOOP+1 ENDDO -
A DOWHILE loop may compute recursive random variables. These are variables that are modified recursively in a dowhile block and which have eta derivatives. For example,
1 2 3 4 5 6 7TERM=THETA(1)*EXP(ETA(1)) SUM=0 ILOOP=1 DO WHILE(ILOOP<=IMAX) SUM=SUM+TERM ILOOP=ILOOP+1 ENDDO - The DOWHILE recursive variable must be initialized to a non-random variable outside the loop and must appear on both sides of the equal sign only once within the DOWHILE loop: V= … V …
-
The syntax is limited, for example the following are not permitted:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16ILOOP=1 DO WHILE(ILOOP<=IMAX) IF (ILOOP == 1) SUM=0 ; initialization within the loop SUM=SUM+TERM ILOOP=ILOOP+1 ENDDO ILOOP=1 DO WHILE(ILOOP<=IMAX) IF (ILOOP == 1) THEN SUM=0 ; initialization within the loop ELSE ; else statement SUM=SUM+TERM ENDIF ILOOP=ILOOP+1 ENDDO - The looping variable ILOOP may also be set and tested and incremented with different integers than shown.
Several examples are present in the examples directory:
- Auto-correlation ("examples/ar1mod")
- Auto-correlation with Simulation ("exmaples/ar1newsim").
- Dose Superposition ("examples/sumdosetn")
- Summing elements of THETA ("examples/superid3_6")
The non-FORTRAN syntax DO WHILE(DATA) is permitted in $PRED initialization and
finalization blocks, and in the $INFN record. (See Initialization-Finalization block).
Conditional
The IF Conditional statements can be paired with ELSE/ELSEIF/ENDIF
or used in one line.
|
|
See below for a restriction on ELSEIF.
Conditions may include the operators .EQ., .NE., .LE., .GE., .LT.,
.GT., .AND., and .OR.. The arthmetic operators may be coded as =,
/, <=, >=, <, and >, respectively. They may include expressions
that can be used as right-hand quantities with assignment
statements. They may not include parentheses except in such
expressions.
|
|
With $PRED, $PK, and $ERROR records, a condition may test the ICALL
argument. However, if the test is IF (ICALL.EQ.2), then ELSE may
not be used. Special rules apply. For more detail, see SPECIAL
STATEMENTS (below), and help entries for these records.
A condition may also test certain variables defined in modules (See variables in NONMEM modules, NONMEM modules).
Abbreviated code in a particular THEN or ELSE clause may not contain multiple definitions of the same random variable. The code below is invalid:
|
|
Random variables cannot be defined within nested conditionals, i.e., within a conditional structure beginning with an IF and containing another IF. The use of ELSEIF … THEN implies a nested conditional.
A special rule applies when random variables are defined via conditional statements. If a random variable is multiply defined within a series of IF … THEN structures, but all conditions are false, then the value of the random variable is set to zero. If an ELSE appears, then not all conditions are false. Consider two cases in which the following statements are the only ones defining TVK and K, respectively:
|
|
If the condition is false, the non-random variable TVK retains the value set with the previous data record.
|
|
If the condition is false, the value of the random variable K is set to zero. NM-TRAN prints a warning message when it detects such code.
In $PK, $ERROR, and $PRED records, recursion code may be used in an explicit manner, as in this example:
|
|
If the condition is false, K retains its value set with the previous
data record. Recursion code can be used in $PRED, $PK, and $ERROR
records for other purposes as well. The following two fragments of
code illustrate how one can use abbreviated code to implement
recursive kinetics in $PRED. The first example works with a single
bolus dose and the second example works with single or multiple bolus
doses. Similar code can be used in $PK and $ERROR.
|
|
The above forms of recursion work for recursion from one data record to the next ("inter-record" recursion). It is also possible to use recursion in a do-while loop ("intra-record", or "do-while" recursion).
Example of a DO-WHILE recursive loop using a random variable:
|
|
A product loop such as
|
|
is also possible, as are other ways the dowhile recursive variable can be used, so long as the variable appears on both sides of the equal sign within the DOWHILE loop: V= … V …
Functions
User-defined function FUNCx, with x
being A, B, … etc. 3 can be used in abbreviated code as
|
|
The X is the vector argument corresponding to the X argument in
the Fortran definition (see below).
The function should be defined with Fortran signature:
|
|
X: input argument (can be a vector).X1:X1(n)is the first-order partial derivative of the function with respectX(n). If the value ofX(n)is not value of a random variable,X1(n)need not be set. If the argument X is a (scalar) expression, only X1(1) is needed.X2:X2(n,m)is the second-partial derivative of the function with respect to the nth and mth elements of the argument. If the value of eitherX(n)orX(m)will not be a value of a random variable,X2(n,m)need not be set. Nor need any value ofX2be set if a test of MSEC=1 is false (see Partial Derivative Indicators). If the argument is a (scalar) expression, onlyX2(1,1)may be needed. If the argument is a vector and if the value ofX2(n,m)is needed, then the value ofX2(m,n)is needed as well, even though these two values will be identical.
The Fortran code for the functions should be placed in one or more files. Suppose there is one such file and its name is funcfile. It should be listed on the $SUBROUTINES record. It may contain more than one FUNCTION, e.g.,
|
|
If the reserved function names are used without but not define by $SUBR OTHER, NONMEM
will emit error such as:
|
|
NONMEM provides reserved variable VECTRA, VECTRB, VECTRC, etc. to be
used as the vector argument X, e.g.
|
|
Note that Vectors defined outside of
$DES (or $AES) may not be used in the $DES (or $AES) block.
NONMEM v7.4+ provides a more flexible way to declare functions and
vector arguments through $ABBR FUNCTION and $ABBR VECTOR (see $ABBREVIATED).
|
|
and define the corresponding Fortran function
|
|
The Function_name must be exactly as specified via $ABBR FUNCTION,
and the same as defined in Fortran source file; the
input_vector_name is the name corresponding to X in the Fortran
definition that one can use in the abbreviated code; the dimension
is passed as NDIM; usage is the maximum number of the function to
be used in the abbreviated code (default to 999). For example, one can
declare
|
|
and use it as
|
|
Alternatively, one can declare a vector with $ABBR VECTOR and use it
in the functions. In this case, use "*" for the function argument,
e.g.
|
|
Note that VQI is shared by the two functions. As shown one can also
use the old pattern.
Pseudo-assignment
Pseudo-assignment statements provide special instructions and must
appear at the beginning of a control record. They may be enclosed in
parentheses. Multiple pseudo-assignment statements enclosed by
parentheses must be semicolon-separated. A common example (may be used
in all records except $MIX) is
|
|
It specifies that all quantities defined in abbreviated code are to be stored locally instead of by default in the (global) MODULE NMPRD4. (Variables in MODULE NMPRD4 can be used for communication between various user-routines, and can be displayed in tables and scatterplots.)
Reserved variables
Entries for $PRED, $PK, $ERROR, $DES,
$AES, $AESINITIAL, and $TOL describe the reserved variable names for
these abbreviated codes. A reserved variable name cannot be used for user-defined variables
unless the pseudo-assignment statement COMRES=-1 is used.
See a list of reserved variables in Module variables, and details in variables.
Index
Indices may be used with user-defined variables that are declared to be arrays using the $ABBR DECLARE record, and also with certain reserved variables:
|
|
Where an index is permitted or necessary, it may be an integer expression. An integer expression is an integer constant, a declared integer variable that has appeared on the left (i.e., has been given a value), a constant defined in SIZES, an expression involving integer constants and integer variables and arithmetic operators +, -, , /, *. It may also be a character string that is replaced by an integer expression using the $ABBR REPLACE feature. The number of indices must be equal to the number of dimensions. If there are two indices, either or both may be constants or expressions. If a indexed variable may be used on the left side, then the index may also be an integer expression. E.g.,
|
|
With reserved random variables such as
ETA(n) EPS(n) ERR(n) A(n) A_0(n)
integer expressions may be used only if they are listed in in WRITE
or PRINT statements. Otherwise n must be an integer constant, or a
character string that is replaced by an integer constant using the
$ABBR REPLACE feature.
Probability density functions
A series of built in probability density functions are available with NONMEM 7.4.2. For a given probability density there is also a cumulative distribution function (densitycdf), and random number generating function (density_rng).
They are described in INTRODUCTION TO NONMEM 7.4.2 Section I.26.
The density and densityCDF functions have arguments that are compatible with the FUNC system, in which function provides derivatives (XD), and second derivatives (XDD) (see I.65.Expanded Syntax and Capacity for User-Defined Functions (FUNCA) (NM74)). Thus, even random (eta associated) variables may serve as arguments to the parameters of the density functions. The source code of these densities are in ..\source\DISTRIB.f90, DISTRIBCDF.f90, and DISTRIBRNG.f90. Note that multi-variate densities do not have a corresponding CDF routine.
Examples of their use are in the ..\examples\densities directory.
|
|
Calling protocol: CALLFL
|
|
- In
$PKabbreviated code: control when PREDPP calls the PK routine. - In
$ERRORabbreviated code: control when PREDPP calls the ERROR routine. - In
$AESINITIALabbreviated code: when the TIME data item is not used, it controls when PREDPP calls the ADVAN9, ADVAN15, or ADVAN17 routine.
The use of CALLFL in each of the three abbreviated codes is independent of its use in the others. The pseudo-assignment statement may be enclosed in parentheses. The pseudo-assignment statement may take these forms:
-
CALLFL=-2: call the PK subroutine with every event record, with additional and lagged doses, and at modeled event times. It does not affect ERROR, ADVAN9, ADVAN15, or ADVAN17 routines.
The following messages will appear in the NONMEM output report:
1 2 3 4 5PK SUBROUTINE CALLED WITH EVERY EVENT RECORD PK SUBROUTINE CALLED AT NONEVENT (ADDITIONAL AND LAGGED) DOSE TIMES or PK SUBROUTINE CALLED AT NONEVENT (ADDITIONAL AND LAGGED) DOSE TIMES AND AT MODEL TIMES -
CALLFL=-1 (default): call the subroutine with every event record.
Correspondingly messages will appear in the NONMEM output:
1 2 3 4 5 6 7 8PK SUBROUTINE CALLED WITH EVERY EVENT RECORD PK SUBROUTINE NOT CALLED AT NONEVENT (ADDITIONAL OR LAGGED) DOSE TIMES ERROR SUBROUTINE CALLED WITH EVERY EVENT RECORD ADVAN9 CALLED WITH EVERY EVENT RECORD ADVAN15 CALLED WITH EVERY EVENT RECORD ADVAN17 CALLED WITH EVERY EVENT RECORD -
CALLFL=0
-
For the PK subroutine: If the data are population data, call the subroutine with the first event record of each individual record; if the data are single-subject data, call the subroutine with the first event record of the data set. In addition, call the subroutine with with every event record where the event time differs from the previous event time.
The following messages will appear in the NONMEM output report:
1 2PK SUBROUTINE CALLED ONLY WITH NEW INDIVIDUAL OR NEW TIME PK SUBROUTINE NOT CALLED AT NONEVENT (ADDITIONAL DOSE OR LAGGED) DOSE TIMES. -
For the ERROR subroutine: When the Simulation Step is being implemented, call the subroutine with every event record. Otherwise, call the subroutine only with observation event records.
The following messages will appear in the NONMEM output report:
1 2DURING SIMULATION, ERROR SUBROUTINE CALLED WITH EVERY EVENT RECORD OTHERWISE, ERROR SUBROUTINE CALLED ONLY WITH OBSERVATION EVENTS - not applicable to the ADVAN9, ADVAN15, or ADVAN17 routine.
With CALLFL=0, The CALL data item may be used to request calls with additional event records.
-
-
CALLFL=1:
-
For the PK and ADVAN9, ADVAN15, or ADVAN17 subroutines: If the data are population data, call the subroutine with the first event record of each individual record; if the data are single-subject data, call the subroutine with the first event record of the data set.
The following messages appear in the NONMEM output report:
1 2 3 4 5 6PK SUBROUTINE CALLED ONCE PER INDIVIDUAL RECORD PK SUBROUTINE NOT CALLED AT NONEVENT (ADDITIONAL DOSE OR LAGGED) DOSE TIMES ADVAN9 CALLED ONCE PER INDIVIDUAL RECORD. ADVAN15 CALLED ONCE PER INDIVIDUAL RECORD. ADVAN17 CALLED ONCE PER INDIVIDUAL RECORD. -
For the ERROR subroutine: When the Simulation Step is being implemented, call the subroutine with every event record. Otherwise, if the data are population data, call the subroutine with the first event record of each individual record; if the data are single-subject data, call the subroutine with the first event record of the data set.
The following messages appear in the NONMEM output report:
1 2DURING SIMULATION, ERROR SUBROUTINE CALLED WITH EVERY EVENT RECORD OTHERWISE, ERROR SUBROUTINE CALLED ONCE PER INDIVIDUAL RECORD
With CALLFL=1, The CALL data item may be used to request calls with additional event records.
-
In a block of abbreviated code, the CALLFL=n pseudo-assignment statement must precede all the other abbreviated code (except for verbatim code or other pseudo-assignment statements). The pseudo-assignment statement may not be used conditionally. CALLFL may not be used as a variable elsewhere in the abbreviated code.
Note that if the $ERROR record consists of only one of these four statements:
|
|
NM-TRAN will automatically limit calls to ERROR to once-per-problem
(unless the Simulation Step is being implemented, in which case.
calls are made with every event record). In effect, this amounts to
yet another way to control when it is that calls may occur to the
ERROR routine, but one which may not be explicitly specified in $ERROR
via the use of CALLFL.
With the last three models above (proportional and exponential), NM-TRAN will also request PREDPP to output the message:
|
|
This does not mean that a model is fit to Log Y data.
A calling protocol phrase may be used within parentheses instead of a pseudo-assignment statement CALLFL. For example
|
|
A calling protocol phrase can be used instead of the CALLFL
pseudo-statement in $PK, $ERROR, and $AESINITIAL abbreviated
codes. The phrase must be enclosed in parentheses. Either upper or
lower case may be used. In an abbreviated code, the line of code
containing the phrase must precede all the other abbreviated code
(except for verbatim code or other pseudo-assignment statements),
and it may be the same line that marks the beginning of the code, as
in the above usage examples. Pseudo-statements defining COMRES may
be coded within the same parentheses, separated by a semicolon ";".
No abbreviated code may follow ")" on the same line as the ")".
-
Phrases equivalent to CALLFL=-2 for the
$PKrecord:1 2(NON-EVENT) (ADDITIONAL OR LAGGED)NONMEM will output the following messages:
1 2 3 4 5PK SUBROUTINE CALLED WITH EVERY EVENT RECORD PK SUBROUTINE CALLED AT NONEVENT (ADDITIONAL AND LAGGED) DOSE TIMES or PK SUBROUTINE CALLED AT NONEVENT (ADDITIONAL AND LAGGED) DOSE TIMES AND AT MODEL TIMES -
Phrases equivalent to CALLFL=-1 for
$PK,$ERRORand$AESINITIALrecords (the default):1 2(EVERY EVENT) (EVERY)NONMEM will output the following messages:
1 2 3 4 5 6 7PK SUBROUTINE CALLED WITH EVERY EVENT RECORD PK SUBROUTINE NOT CALLED AT NONEVENT (ADDITIONAL OR LAGGED) DOSE TIMES ERROR SUBROUTINE CALLED WITH EVERY EVENT RECORD ADVAN9 CALLED WITH EVERY EVENT RECORD. ADVAN15 CALLED WITH EVERY EVENT RECORD. -
Phrases equivalent to CALLFL=0 for the
$PKrecord:1 2(NEW TIME) (NEW EVENT TIME)NONMEM will output the following messages:
1 2PK SUBROUTINE CALLED ONLY WITH NEW INDIVIDUAL OR NEW TIME PK SUBROUTINE NOT CALLED AT NONEVENT (ADDITIONAL OR LAGGED) DOSE TIMES. -
Phrases equivalent to CALLFL=0 for the
$ERRORrecord:1 2 3 4(OBSERVATION EVENT) (OBS) (OBSERVATION ONLY) (OBS ONLY)NONMEM will output the following messages:
1 2DURING SIMULATION, ERROR SUBROUTINE CALLED WITH EVERY EVENT RECORD OTHERWISE, ERROR SUBROUTINE CALLED ONLY WITH OBSERVATION EVENTS -
Phrases equivalent to CALLFL=1 for the
$PK,$ERRORand$AESINITIAL:1 2(ONCE PER INDIVIDUAL RECORD) (ONCE/IND.REC.)NONMEM will output the following messages:
1 2 3 4 5 6 7 8PK SUBROUTINE CALLED ONCE PER INDIVIDUAL RECORD PK SUBROUTINE NOT CALLED AT NONEVENT (ADDITIONAL OR LAGGED) DOSE TIMES DURING SIMULATION, ERROR SUBROUTINE CALLED WITH EVERY EVENT RECORD OTHERWISE, ERROR SUBROUTINE CALLED ONCE PER INDIVIDUAL RECORD ADVAN9 CALLED ONCE PER INDIVIDUAL RECORD. ADVAN15 CALLED ONCE PER INDIVIDUAL RECORD.
Verbatim code
USAGE:
|
|
Verbatim code is Fortran code within a block of abbreviated code that is to be copied by NM-TRAN to the generated Fortran subroutine. It is not itself regarded as abbreviated code. Such code is marked by having the character " as the first non-blank character. The " is dropped and the characters to the right are copied as-is to columns 1-72 of the generated subroutine. Lines of verbatim code can include any Fortran statements: comment, declaration (e.g., INTEGER, COMMON, USE), I/O, CALL, assignment, continuation, DO, GOTO, etc.).
NM-TRAN makes some modifications to verbatim code:
- Placement: the verbatim code is adjusted as necessary to conform to FORTRAN column conventions. Alphabetic text that follows the initial ", or that follows a statement number, is moved to column 7, as required by FORTRAN.
- Comment lines: If the character that immediately follows the initial " is !, this conforms to the FORTRAN 90 syntax for comment lines. The line is copied unchanged. If the character that immediately follows the initial " is C or c or " or *, this conforms to the FORTRAN 77 syntax for comment lines. The line is copied unchanged, but C or c or " or * is replaced by !.
-
Continuation lines: Fortran 77 continuation lines (non-blank in position 6) are not permitted with NONMEM 7. Instead, the line to be continued should end with character &. Example:
1 2" X=A & " +D/E - Replacement Rule: in
$PK,$ERROR,$DES,$AES,$INFN, and$PRED, in a line of abbreviated code labels of items in the data record are replaced by direct references to the data record itself (either DATREC or EVTREC, as appropriate). Thus, for example, if such a label occurs as the left-hand side of an assignment statement, then without this rule, when the statement is executed, the value of a local variable having the label is modified, whereas with the rule, an item in the data record is modified.
The character @, immediately before a label, can be used as an "escape" to prevent the label from being replaced. If the character @ immediately follows the initial ", none of the labels occuring in the line are replaced.
Labels occurring in common statements or as subroutine arguments are never replaced.
Tab characters (and other characters that are smaller than blank in the computer's collating sequence, such as carriage return ^M) are permitted in verbatim code. With NONMEM 7, the last non-blank character on the line is replaced by a space if it is a low-value character. This permits DOS-type line endings ^M.
By default, all verbatim code goes in the main section of code and is called MAIN verbatim code. (The main section follows declarations and initial executable code inserted by NM-TRAN.) Within the main section, verbatim and abbreviated code may be freely mixed. Each line of verbatim code is positioned in the generated code after all code generated from the preceding line of abbreviated code. The user may explicitly specify a different location as follows.
- FIRST verbatim code: Verbatim lines which must be positioned immediately after the declarations which are part of the normal subroutine header, and prior to the FIRST executable statement of the subroutine, must precede the first line of abbreviated code and must start with the line "FIRST.
- MAIN verbatim code: FIRST verbatim code is normally terminated by the first line of abbreviated code. If there is both FIRST and MAIN verbatim code, and/or the main section is to start with verbatim code, the line "MAIN may be used to separate the FIRST and MAIN verbatim code.
-
LAST verbatim code: Verbatim lines which are to immediately precede the RETURN statement from the generated subroutine must follow the last line of abbreviated code and must be preceded by the line "LAST.
Example:
1 2 3 4$ERROR Y=F*(1+ERR(1)) "LAST " PRINT *,HH(1,1)This displays values after they have been assigned, immediately prior to the return.
If any lines of verbatim code are present in a block of abbreviated code, NM-TRAN generates USE statements appropriate to the kind of abbreviated code and allows variables undefined in abbreviated code to be used as right-hand quantities in abbreviated code.
Reserved and other functions
With verbatim code advanced users can also access many internal NONMEM
variables. For example variable ITER_REPORT that contains the present
iteration number as in the output may be used within the $PK, $ERROR,
or $PRED code. To access these variables in certain block one needs to place the
corresponding MODULE definitions in an include file with name that
begins with "NONMEM_RESERVED" (case insensitive) at the beginning of
the control record block. NONMEM provides file util/nonmem_reserved_general
that has many such variables, including ITER_REPORT, in the form of
verbatim code:
|
|
For example, to use nonmem_reserved_general in $PK, place the file
in the present run directory, and do ("examples/example8"):
|
|
The nonmem_reserved_general file also contains function
declarations, such as TFI and TFD, which are convenient functions to
easily convert an integer to text (“text from integer” TFI) or double
precision value to text (“text from double” TFD). They can be used to
to have compiler can catch a misuse of that function’s arguments. If
you wish to define your own function, and have the information about
its proper use of arguments be conveyed upon its execution, so the
compiler may detect errors, then one method is to package the
definition of the function in a USE module. For example,
myfuncmodule.f90 below defines the functions mymin and mymax.
|
|
One can create file nonmem_reserved_myfunc to declare:
|
|
and use it in control stream files:
|
|
Then compiler will flag errors on mistaken argument use.
EXIT
EXIT statement has three forms:
|
|
n is called the "PRED error return code"; (also called the "PRED exit code.") It must be 1 or 2. Default is 1. k is the user error code. It may be omitted; if present, it must be integer-valued in the range 0-999. With NONMEM 7.5, it may also be in the range 1000-9999 when issued during the Simulation Step. Default is 0.
With all versions of NONMEM, the value of k is part of the error message in ETEXT, which is reported in the NONMEM output report and in file PRDERR. With NONMEM 7.5 and later, k tells NONMEM how to handle EXIT statements during the Simulation Step.
(See Simulation block).
(See PRED EXIT code).
The EXIT statement causes an immediate exit from the routine and, if PREDPP is being used, a subsequent immediate exit from PREDPP, with a return to NONMEM. It is typically used in an IF statement to avoid further computation of the users code when the values of theta/eta's set by NONMEM are inappropriate or would lead to an arithmetic exception. If such an exit occurs during a Covariance, Table or Scatterplot Step, or during computation of the initial value of the objective function, NONMEM will abort. If the exit occurs during an Estimation or Initial Estimates Step, NONMEM's action depends on the error return code value:
- n=1. Suppose first that a search for eta is not underway. Then a search for theta is underway, and when a search is underway for THETA. If the NOABORT option is used then NONMEM will try to continue using different values for THETA. If THETA recovery also fails, NONMEM will aborts. Without the NOABORT option, NONMEM will simply abort. Similarly, if a search for ETA is underway. NONMEM will try to continue using different values for ETA. If this ETA recovery fails, and a search for THETA is not also underway, NONMEM will abort. Otherwise, the above procedure regarding THETA-recovery applies. See also Error recovery.
- n=2. NONMEM aborts immediately.
If NONMEM aborts, and k>0, a user message such as the following is printed in the output: "PK SUBROUTINE: USER ERROR CODE = k" This message is intended to help the user distinguish which EXIT statement caused NONMEM to abort when more than one EXIT statement is present in the abbreviated code.
File and output
Fortran statements of WRITE, PRINT, OPEN, CLOSE, and REWIND
may be used in $PRED, $INFN, $PK, $ERROR, $DES, $AES, $AESINITIAL
blocks, such as
|
|
and
|
|
Single or double quotes around the filename are optional. However, if the filename contains commas, semicolons, or parentheses, then it must be surrounded by single quotes ' or double quotes ". Filename may also contain equal signs if it is enclosed in quotes.
If the file is opened by NM-TRAN, filename may contain embedded spaces if it is enclosed in quotes, and may contain at most 80 characters. If the file is opened by NONMEM, filename may not contain embedded spaces, and may contain at most 71 characters.
-
Unit 6, n or *
- "6" indicates the unit connected to the NONMEM output file.
- "n" indicates the number of an alternative unit (40<n<2000).
- "*" indicates a FORTRAN system-dependent output (with most systems, this is equivalent to using unit 6, but see the FORTRAN documentation) With OPEN, CLOSE and REWIND, the unit may not be 6 or *.
-
Format *, 1, 2, 991, or 992 4 5
- "*" indicates list-directed output. (FORTRAN library routines will select a format appropriate for the current run-time value of the quantity when displayed.)
- 1 or 991 requests the built-in format specification: 991 FORMAT (35F14.4)
- 2 or 992 requests the built-in format specification: 992 FORMAT (35E15.7)
- List. A list of one or more right-hand quantities, i.e., variables or constants that may appear on the right in abbreviated code. May not include expressions or names of abbreviated functions. When indices are appropriate, these must be integer constants, declared integer variables, or expressions involving such constants and variables.
With a PRINT statement, a list may also include character constants. A character constant is delimited by single or double quotes (' or "). As with any Fortran character constant, a pair of adjacent delimiters within the constant represents a single character, e.g.,
|
|
will output
|
|
In an Initialization or Finalization block, a list may include elements of the OMEGA and SIGMA arrays. In a finalization block, a list may include elements of the standard error arrays (SETHET,SETHETR,SEOMEG and SESIGM).
Any array whose elements may be listed individually in a WRITE or PRINT statement may also be written in its entirety, by listing it without any indices. Specifically, one or more of the following may be included in a list:
|
|
Note that IIDX and CNTID are arrays in a module; (See Objective Function Value Individual). When "IIDX" or "CNTID" is listed, then only that array is written. When "IIDX,CNTID" is specified, then pairs of values are written, one pair per line, one pair for each individual record.
The option BLOCK requests that the entire array be written in full symmetric form. The option DIAG requests that only the diagonal elements be written. DIAG may also be coded DIAGONAL. Arrays of possibly different sizes (e.g., OMEGA and SIGMA) may not be listed together in the same WRITE statement. If a WRITE statement requests that an entire array be written, then the only other items that may be listed with the statement are other entire arrays.
When entire arrays are written, the format specification with a WRITE statement must be *. With either a WRITE or PRINT statement, an appropriate format is created by the NONMEM system. With these for mats, elements of the standard error arrays that do not exist have the value 1E10 and are printed as 0.1000000E+11. (Such elements appear in NONMEM output as dots (………).) If the covariance step fails or is not requested, all elements of the standard error arrays are 0 and are printed as 0.0000000E+00. For example, to write the omega matrix and its standard errors in symmetric form code the following. (Only as many elements will be written as are appropriate for the dimension of omega in the problem.)
|
|
A list may also include a vector element or the entire vector (by listing the vector without an index).
The OPEN, CLOSE, and REWIND statements are part of the FORTRAN language. For details (i.e., the relationship of external files to units), see the Language Reference Manual and the Users Guide for your compiler.
PASS
|
|
may be used only in $PRED Initialization-Finalization blocks and in $INFN records. If present,
MODE becomes a reserved variable with type INTEGER, and may not be
used outside the block(s).
SUPP
|
|
ie and ic are of integer values 0 or 1. Value 1 of ie / ic suppresses output from the
Estimation/Covariance step. A value 0 does not suppress the output
from the step. May be used only in $PRED initialization-finalization
blocks, and in $INFN records. The ie / ic value remains in effect
until changed by a call to SUPP.
RANDOM
|
|
n: integer 1-10. It is the number of the random source. R: a
random number from this source. May be used only in Simulation and
Expectation blocks. If present, R becomes a reserved variable with
type REAL, and may not be used outside the block(s).
SIMETA, SIMEPS
|
|
May only be used in Simulation blocks. Note that NM-TRAN itself provides the minimum necessary call to SIMETA/SIMEPS. This statement is used in abbreviated code only to obtain a different value of ETA/EPS, e.g., so that the ETA distribution may be truncated:
|
|
RETURN
|
|
may be used in all special blocks. RETURN statements must be used with caution because they by-pass certain normal final actions of the routine. See code blocks below for its use.
Code blocks
Abbreviated code blocks are used to achieve special tasks.
| Block | Usage |
|---|---|
| Compartment initialization block | $PK abbreviated code |
| Compartment update block | $PK abbreviated code |
| DATA_AVERAGE block | Abbreviated code |
| PRED_IGNORE_DATA block | $PRED, $PK, $INFN abbreviated code |
| Initialization-finalization block | $PRED, $PK, $ERROR, $INFN abbreviated code |
| Copying block | $PRED, $PK, $ERROR, $AES, $DES abbreviated code |
| Simulation block | Abbreviated code |
| Expectation block | Abbreviated code |
The code blocks heavily utilize reserved variable ICALL to
distinguish NONMEM executation stages.
ICALL
ICALL is an argument passed by NONMEM to user-supplied
subroutines CCONTR, CONTR, CRIT, PRED, PRIOR and MIX. It is also
selectively passed to PK, ERROR, and INFN. It can be used in
$PK, $ERROR, and $PRED abbreviated code. The discussion below
describes the values of ICALL as seen by PRED.
- ICALL=-1: the routine has been called for the
PRED_IGNORE_DATA(NM 7.5). One call per data record, at the start of the run. These calls occur only if abbreviated code uses variablesPRED_IGNORE_DATAorPRED_IGNORE_DATA _TEST, or the$DATA PRED_IGNORE_DATAoption. - ICALL=0: the routine has been called for initialization at the beginning of the NONMEM run; one such call per run.
- ICALL=1: the routine has been called for initialization at the beginning of a NONMEM problem; one such call per problem.
- ICALL=2: the routine has been called for a prediction. Multiple calls occur.
- ICALL=3: the routine has been called for finalization at the end of a NONMEM problem; one call per problem.
- ICALL=4: the routine has been called during the Simulation Step; multiple calls occur.
- ICALL=5: the routine has been called when expectations are being computed; multiple calls occur.
- ICALL=6: the routine has been called when raw data averages are being computed; multiple calls occur.
- Some subroutines are called with only a subset of the possible values of ICALL.
Compartment initialization
Usage:
|
|
A "compartment initialization block" is abbreviated code in $PK block
that sets A_0, the initial state of the kinetic system, when
the read-only global variable A_0FLG has value 1. PREDPP sets A_0FLG=1 at a call to PK with the first event
record of an individual record (if the data are population data), with
the first event record of the data set (if the data are
single-subject data), and with a reset record.
Special rules:
- Values may be assigned to reserved variables A_0(n), but only in a compartment initialization block. The value of the amount in the nth compartment (the nth element of the state vector) is set to the value assigned to A_0(n). If PK is called with a dose record or a dose-reset record where the dose is input into the nth compartment, this amount is then increased by the amount of the (bioavailable) dose. If a value is assigned to A_0(n), then it is not necessary that values be assigned to any of the remaining variables A_0(m). A value to the output compartment cannot be assigned. A_INITIAL(n) is a synonym for A_0(n).
- The statement "IF (A_0FLG.EQ.1)" and the corresponding "ENDIF" statement may be included explicitly in abbreviated code, thus defining an explicit compartment initialization block. See example below.
- A_0(n) may be assigned a value with an unconditional statement. This defines an implicit compartment initialization block; NMTRAN inserts "IF (A_0FLG.EQ.1) …" before the statement and "ENDIF" after it. (See example 2 below.) Indicator variables may be included in the unconditional statement. See example below.
- An IF statement testing ICALL and A_0FLG together is not permitted. Instead, two separate nested IF statements must be used: an IF statement testing ICALL must occur as the outermost statement, and an IF statement testing A_0FLG must occur as the innermost statement. The latter may be supplied by NM-TRAN as a result of using an implicit initialization block. See example below.
- Within an explicit compartment initialization block, A_0(n) may be assigned conditionally. The usual rules apply if A_0(n) is a random variable. E.g., A_0(n) cannot be assigned within a nested IF, and it defaults to 0 if it is assigned conditionally but incompletely. However, in checking for a nested IF, tests of A_0FLG and of ICALL are ignored. See example below.
- User-defined variables may be defined in compartment initialization blocks, but not reserved variables such as basic or additional PK parameters.
Consider the following examples.
-
The following two fragments of code yield identical results: Explicit compartment initialization block:
1 2 3IF (A_0FLG.EQ.1) THEN A_0(1)=THETA(1)*(1+ETA(1)) ENDIFImplicit compartment initialization block:
1A_0(1)=THETA(1)*(1+ETA(1)) -
Conditional assignment of A_0(n), depending on a data item or user-defined variable X.
1 2 3 4 5 6 7IF (A_0FLG.EQ.1) THEN IF (X.EQ.1) THEN A_0(1)=THETA(1)*(1+ETA(1)) ELSE A_0(1)=THETA(2)*(1+ETA(2)) ENDIF ENDIFAn alternative is to use an indicator variable. E.g., if X is a 0/1 variable, then the above is equivalent to
1A_0(1)=X*THETA(1)*(1+ETA(1))+(1-X)*A_0(1)=THETA(2)*(1+ETA(2)) -
Suppose compartment initialization should occur only during the Simulation step. The following is not permitted:
1IF (ICALL.EQ.4.AND.A_0FLG.EQ.1) A_0(1)=THETA(1)*(1+ETA(1))Instead, use:
1 2 3IF (ICALL.EQ.4) THEN IF (A_0FLG.EQ.1) A_0(1)=THETA(1)*(1+ETA(1)) ENDIFor simply
1 2 3IF (ICALL.EQ.4) THEN A_0(1)=THETA(1)*(1+ETA(1)) ENDIFor even better
1IF (ICALL.EQ.4) A_0(1)=THETA(1)*(1+ETA(1))
See also PK subroutine.
Compartment update (NM75)
Usage
|
|
Similar to compartment initialization block, in a compartment update block, the user sets A_UFLG to 1 in PK to indicate to PREDPP that PK is going to update the compartments. The desired compartment values may be set in the array A_U(n). The user should use MTIME to designate a variable time position at which an abrupt change in compartment amounts occurs. One could input a dose as follows:
|
|
The A_UFLG event must be triggered with an IF(TSTATE==MTIME())
condition as indicated in the above example. Values may be assigned
to reserved variables A_U(n). The value of the amount in the nth
compartment (the nth element of the state vector) is set to the value
assigned to A_U(n). Any A_U(x) not explicitly defined are set
to 0. An un-assigned A_U(k) should retain its value, A_u(k)=A_u(k).
- The code "IF(A_UFLG==1)…THEN…ENDIF" is optional, as NMTRAN will insert it if not present. A_0FLG must be 0 whenever A_UFLG is set to 1, as shown in the example above.
- The rules for compartment update blocks are similar to those for compartent initialization blocks.
- PREDPP expects to find the A_U values in the A_0 arrays. NMTRAN converts A_U() in abbreviated code to A_0() during FSUBS code construction.
See $PK for details.
Data average
Usage:
|
|
A data average block is a block of abbreviated code that is only
executed when ICALL=6. This value of ICALL occurs when the RAW_
data item is defined in the data set and has a non-zero value for some
records. Data average blocks are not required when the
raw-data-average data item is present, but they allow the user
additional functionality. Such blocks may be present in $PRED and
$ERROR. If for a given observation record matching a template
record, a data average block sets the DV variable to a value different
from the one in the record, this value is the one included in the
average.
In the following example, the displayed DV value for each template record is the proportion of DV items greater than 10 on those records matching the template record.
|
|
PRED may return a value of 1 in F, indicating that the DV item in the record is not to be included in the average. Continuing the above example, suppose that the DV variable is set to a value only when it exceeds 2, so that the average is the proportion of observations exceeding 10 among those that exceed 2. The code is as follows. See note 2 below on the returned value of F.
|
|
When ICALL=6, PRED and ERROR are called with successive records as usual. However, with each observation record, all output from these routines other than a value set for the DV data item and values set for PRED-defined (ERROR-defined) items V used in a table or scatterplot and located in the SAVE region (and the F value, in so far as it is or is not 1) is ignored. In the same way that an average is formed for the DV, averages are formed for the elements of V. Upon entry into PRED or ERROR with a given record, the value of the DV item is the one on the record, and the values for V are the values that will be used in a table and/or scatterplot. If PRED or ERROR changes one of these values, the new value is the one used in the average. If a value is not changed, the unchanged value is used in the average. (For a nonobservation record, the output from that record is completely ignored.)
The following series of examples concern taking averages of PRED- defined items. They involve a mixture model, where, under each of the subpopulations, there is a parameter PA whose value depends on an ETA. There is a template record.
Example A
Suppose first that PA does not depend on (interindividually-varying) covariate values. Suppose moreover, that during copying passes, with each individual record a value of the quantity Q=P1*PA1+P2*PA2+P3*PA3 has been computed and stored in the SAVE region. Here, the P's are the mixture probabilities, and the PA's are conditional estimates of PA under the different models for the different subpopulations. Due to the presence of the template record, at ICALL=6, the average of Q across the eta estimates (from individuals with the same covariate values as are contained in the template record) will be computed - without any need for a data average block. More precisely, at ICALL=6 a pass through the data set occurs, during which a value of Q is obtained with each of the observation records that match the template record. However, the average of the Q values is an average of within-individual averages, and since Q does not vary within an individual record, the within-individual average computed for that record is the same value of Q as is obtained with each of the observation records of the individual record (matching the template record). The resulting average of the Q values is an estimate of the expected value of PA over the subpopulations and the randomly-varying PA's.
Example B
Suppose that PA depends on a covariate X E.g. PA=THETA(1)*X**THETA(2)*EXP(ETA(1)), and that one is interested in an estimate of the expected value of PA for X=x. Suppose also that the value for X in the template record is x. Once again, suppose that during copying passes, with each individual record a value of Q has been computed and stored in the SAVE region - using whatever value of X appears in the individual record. At ICALL=6, if and only if the observation records within an individual record have the value X=x and match the template record with respect to the other relevant data items, will the within-individual average be included in the average Q. Moreover, these observation records are the very ones whose value for Q is of interest.
Example C
Under a well-specifed model, ETA(1) should be independent of X, and so one might want to use an average of Q across the eta estimates from all individuals (with observation records). Then one might (i) during copying passes, for each individual record compute Q using the specific value X=x - regardless of what value of X appears in the individual record, and (ii) include the record
|
|
to prevent the values of X from affecting the match with the template record.
Example D
The strategy in example C fails if it is necessary to match on X for the purpose of forming averages other than the average Q, and it is at least awkward if one is interested in the expected value of PA for a variety of values of X. Here is an alternative strategy.
|
|
During the copying passes, the values of the eta estimates are stored (in items COM(1), COM(2) and COM(3) of the SAVE region) rather than the value of Q. The first table record appears because unless the items COM(1), COM(2), and COM(3) are displayed, at ICALL=6 their values are 0. TEMPLT(X) refers generically to the value of X on the template record (see Special Rule 4 below); so there can be numerous template records with different values of X.
Example E
Examples A-C are not explicit about how the mixture probabilities are computed. They might be obtained via MIXP, in which case during the copying passes (similar to what happens at ICALL=6 with example D), with a given individual record, they are the probabilities pertaining to that record. As long as the mixture probabilities do not depend on interindividual-varying covariates, the mixture probabilities are the same no matter what individual record it is to which they pertain. But if the probabilities depend on interindividual-varying covariates, and especially if one wants to estimate the expected value of Q for numerous different sets of values for these covariates, then one might use:
|
|
The mixture probabilities found in MIXPT pertain to the individual record containing the template record (see Special Rule 7 below). Because they have been computed using the covariate values in that record, they are commensurate with the way PA has been computed for the different subpopulations. With versions prior to NONMEM 7.3, the probabilities in MIXPT must be referenced via verbatim code (note the double quotes).
|
|
Special rules
- No ETA derivatives are computed in a data average block.
- A RETURN statement may be used in a data average block. If Y= appears (i.e. Y is assigned a value) in a data average block before the RETURN (not necessarily in the same block containing the RETURN), then F is set to Y (F=Y); otherwise F is set to to 0 (F=0). If there is no RETURN statement in a data average block, then as usual, F is set to the value of Y assigned by the time PRED (ERROR) exits.
-
Loops are permitted in a data average block. The syntax is as follows.
1 2 3DO WHILE (condition) .. statements .. END DO - During calls with ICALL=6, the template data record is found in NONMEM global variable TEMPLT. Items in the template data record may be referred to in abbreviated code of the data average block by position or by label, e.g., TEMPLT(1) or TEMPLT(ID).
- During calls with ICALL=6, the repetition feature may not be used.
- If a mixture model is used, then during calls with ICALL=6, both MIXNUM and MIXEST are the index of the subpopulation into which the individual (whose data record is being passed) has been classified.
- If a mixture model is being used, then during calls with ICALL=6, (the final estimates of) the mixture probabilities associated with the individual record containing the template record are found in NONMEM global variable MIXPT. Code that uses these probabilities must be verbatim code. (See MIX CONTR: TEMPLT, Mixture model: MIXPT).
PRED_IGNORE_DATA (NM75)
Usage:
|
|
Usage (in user-defined function):
|
|
The $DATA IGNORE=(list) and $DATA ACCEPT=(list) options provide a limited
means of filtering the input data set, which is performed by NMTRAN.
To provide more elaborate filtering for excluding data, PRED can
request that NONMEM filter out additional data records at the
beginning of the run. This is done by setting the reserved variable
PRED_IGNORE_DATA to a non-zero value within $INFN, $PK, or $PRED, for
each record to be ignored.
-
It may be useful to package PRED_IGNORE_DATA statements within
1 2 3 4IF(PRED_IGNORE_DATA_TEST==1) THEN ... RETURN ENDIFstructures to avoid unnecessary code execution.
-
If the PRED_IGNORE_DATA_TEST or PRED_IGNORE_DATA variables appear in abbreviated code, or the option
$DATA ... PRED_IGNORE_DATAis used in the NM-TRAN control stream, then aPRED_IGNORE_DATApass through the NONMEN data file withPRED_IGNORE_DATA_TEST=1and ICALL=-1 occurs. Otherwise it does not. Therefore, existing code such as1 2 3IF (ICALL<=1) THEN ;! ... ENDIFdoes not need to be changed.
-
The following variables have properly defined values:
- ICALL
- Data record items in DATREC
- NEWIND,NEWL2
- NPROB,IPROB, S1NUM, S2NUM,
- S1NIT,S2NIT, S1IT, S2IT
- No other variables are properly defined when PRED_IGNORE_DATA_TEST=1. For example, the following should not be used: THETA, OMEGA, SIGMA, NREP, IREP ETA may be used but will be 0 there are no random variables in a pred_ignore_data block.
- Typically the NONMEM file that is input to the pred_ignore_data block is FDATA. FDATA is unaffected by the pred_ignore_data block. However, with NONMEM 7.5 there is a new file, FDATA.csv, and records excluded by PRED_IGNORE_DATA will not be present in FDATA.csv.
- In a pred_ignore_data block, the data record has been read by
NONMEM and all data record items have numeric values. The
(non-Fortran) operators .EQN. and .NEN. that can be used with the
$DATA IGNOREandACCEPToptions are not needed and cannot be used in a pred_ignore_data block. - Any other functions of
$INFN, such as DATA item modification (i.e., transgeneration of the data), RANDOM calls, etc. should be made with ICALL==1 or ICALL==0 IF blocks, as before. -
It is possible to restrict PRED_IGNORE_DATA actions to a particular problem number:
1 2 3 4 5 6IF(IPROB==2.AND.PRED_IGNORE_DATA_TEST==1) THEN PRED_IGNORE_DATA=0 IF(AGE>35.0) PRED_IGNORE_DATA=1 IF( ID>10.AND.ID<18.OR.ID>60.AND.ID<70 ) PRED_IGNORE_DATA=1 RETURN ENDIF - RETURN statements may be used.
- EXIT statements may be used. They act like a RETURN but are otherwise ignored.
See "Reference Manual: $DATA" for details.
Initialization-finalization
Usage:
|
|
A run consists of one or more problems, and each problem consists of one or more subproblems, which are iterations of various tasks specified in the problem. The "end" of a subproblem refers to the end of such an iteration. Problems themselves may be organized into super-problems, which may be iterated. The "beginning" and "end" of a superproblem refers to the beginning and end of the first and last iterations of the superproblem. There are opportunities to make some rudimentary computations at:
- the beginning of a run (run initialization);
- the beginning of a superproblem (superproblem initialization);
- the beginning of a problem (problem initialization);
- the end of a subproblem (subproblem finalization);
- the end of a problem (problem finalization);
- the end of a superproblem (superproblem finalization);
- the end of a run (run finalization).
For example, data transgeneration may take place at problem initialization. Or, a variable may be initialized at problem initialization and modified at each subproblem finalization, and its final value written to a user file at problem finalization. There is no opportunity to do subproblem initialization. When using abbreviated code, initialization and finalization opportunities are signalled by values of the variable ICALL:
- ICALL=0: Run initialization.
-
ICALL=1: Superproblem and Problem initialization. ICALL is set to 1 to signal problem initialization. When this happens, if a superproblem requires initialization, test
- S1IT (number of current superproblem iteration) equals 1 (or S2IT=1),
- S1NUM (number of current superproblem) equals appropriate value, and
- IPROB (number of current problem) equals number of first problem in superproblem,
If 1-3 are true, do superproblem initialization (See problem Iteration Counters).
-
ICALL=3: Subproblem, Problem, Superproblem and Run finalization. ICALL is set to 3 to signal problem finalization. When this happens:
- If a problem with subproblems requires finalization, test IREP=NREP (number of the current subproblem equals total number of subproblems) and if true, do problem finalization (See Simulation: NREP,IREP).
-
If a superproblem requires finalization, test
- S1IT=S1NIT (number of the current superproblem iteration equals total number of superproblem iterations) (or S2IT=S2NIT),
- S1NUM (number of current superproblem) equals appropriate value,
- IPROB (number of current problem) equals number of last problem in the superproblem, and
- IREP=NREP, if there are subproblems with the last problem in the superproblem
If (i)-(iv) are true, do superproblem finalization.
-
If a run having multiple problems requires finalization, test
- S1IT=S1NIT (or S2IT=S2NIT), if there are superproblems
- S1NUM equals number of last superproblem, if there are superproblems,
- IPROB=NPROB (number of the current problem equals total number of problems), and
- IREP=NREP, if there are subproblems with the last problem in the superproblem.
If (i)-(iv) are true, do run finalization.
An initialization block is a block of abbreviated code that is only executed at ICALL=0 or ICALL=1. A finalization block is a block of abbreviated code that is only executed at ICALL=3. E.g.,
|
|
Such blocks may be present in $PRED, $PK, $ERROR, and $INFN blocks of
abbreviated code. If such blocks are present in $PK or $ERROR, an
INFN routine is used to implement the logic in these blocks.
Initialization and finalization blocks will be implemented by means of
a generated FORTRAN subroutine.
Variables may be used as right-hand quantities even before they are defined; if an expression which uses such a variable is computed before any value of the variable is computed, the computation of the expression will be uncertain.
Assignment, conditional, WRITE and PRINT statements may be used.
In addition, these rules apply:
- Defined quantities are not regarded as random variables; eta derivatives are not computed in an initialization or finalization block.
- Transgeneration of the data is permitted. NONMEM data items ID and MDV may not be changed. If a data item label may appear on the left of an assignment statement, then NM-TRAN generates assignment statements changing first the data item in the event or data record, and then the value of the local variable having that label. Note, however, that at ICALL=0,1,or 3, by default, references to data items are references to those data items in the first data or event record. To transgenerate an item in any data or event record (including the first), use of the NONMEM utility routine PASS is required. See below.
-
Calls to certain NONMEM routines are permitted:
1 2 3CALL PASS(MODE) CALL RANDOM(n,R) CALL SUPP(ie,ic)CALL PASS(MODE) must be coded exactly in this way. If CALL PASS(MODE) is present, MODE becomes a reserved variable and may be used only with other instances of CALL PASS(MODE). Multiple calls to PASS may be present.
If CALL RANDOM(n,R) is present, R becomes a reserved variable and may be used only with other instances of CALL RANDOM(n,R). n may only be an integer value 1-10.
- SUPP is used to suppress portions of the NONMEM output report. (See supp). The arguments ie and ic may only be 0 or 1.
-
The following variables may be used on the right (their values change with calls to PASS):
- Data record items (See PASS: PASSRC).
- NEWIND (See PASS NEWIND: NWIND).
- NIREC, NDREC (See Record Counters: NIREC,NDREC).
- NEWL2 (See PASS New L2 record: NEWL2).
- ETA when ICALL=3 (See Simulation: ETA,EPS)
- LIREC (See Size of Individual Record)
- PRED_, RES_, WRES_ when ICALL=3 (See PRED,RES,WRES).
- IERE, IERC when ICALL=3 (See Estim Covar Error Codes).
- NINDR, INDR1, INDR2 (See NINDR INDR1 INDR2).
- NREP, IREP (See Simulation: NREP,IREP).
- NPROB, IPROB, S1NUM, S2NUM, S1NIT, S2NIT, S1IT, S2IT (See problem Iteration Counters.)
- RETURN and EXIT statements may be used.
-
DOWHILE loops are permitted. The syntax is as follows.
1 2 3DO WHILE (condition) .. statements .. END DOHere is an example of a transgeneration loop.
1 2 3 4 5 6 7 8 9 10 11 12$PRED IF (ICALL.EQ.0) THEN MODE=0 CALL PASS (MODE) MODE=2 CALL PASS (MODE) DO WHILE (MODE.EQ.2) ... transgeneration statements ... CALL PASS (MODE) ENDDO RETURN ENDIFThis type of usage of the PASS routine can be coded more simply, as follows:
1 2 3 4 5 6 7$PRED IF (ICALL.EQ.0) THEN DOWHILE (DATA) ... transgeneration statements ... ENDDO RETURN ENDIFDOWHILE (DATA)has the transgeneration statements executed with each data record. In effect, NM-TRAN supplies the statementsMODE=...andCALL PASS(MODE)that are shown in the above. - Variables that are first defined in an initialization block or finalization block are not stored globally in NMPRD4, but rather, are stored in module PRINFN. (This makes them available to subroutine MIX.)
- Variables defined in an initialization or finalization block may be used freely outside of such blocks, and vice versa: PRED-defined variables defined outside such blocks may be used within them.
-
THETA variables may be used in initialization and finalization blocks. They are obtained from the subroutine argument.
- At ICALL=0, THETA contains the initial estimates for the first problem.
- At ICALL=1, THETA contains the initial estimates for the current problem.
- At ICALL=3, THETA contains the final estimates for the current problem.
Here is an example of code that could be used during a simulation with multiple subproblems.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15$PRED IF (ICALL.EQ.1) THEN SUM=0 N=0 RETURN ENDIF IF (ICALL.EQ.3) THEN N=N+1 SUM=SUM+THETA(1) RETURN ENDIF IF (ICALL.EQ.3.AND.N.EQ.NREP) THEN MEAN=SUM/N PRINT *,MEAN ENDIFThe following variables may be referenced as right-hand quantities in initialization and finalization blocks. (Note also that unindexed arrays may appear in a WRITE statement.)
1 2OMEGA(n,m) SIGMA(n,m)(See Parameter Values: Initial and Final). (See write print).
-
The following variables may be referenced as right-hand quantities in finalization blocks. (Note also that unindexed arrays may appear in a WRITE statement.)
1 2 3 4 5SETHET(n) SETHETR(n) SEOMEG(n,m) SESIGM(n,m) OBJECT(See Standard Errors). (See Objective Function Value). (See write print).
-
The following statements are forbidden:
1 2CALL SIMETA(ETA) CALL SIMEPS(EPS) - When the PRED repetition feature is used, the variables RPTO and PRDFL may appear as left-hand quantities in initialization blocks. (See Repetition Variables).
As a practical example, the abbreviated code below can be inserted in a $PRED or $INFN
block to output final parameter estimates, standard errors, minimum value of
the objective function, and conditional estimates of ETAs to various user files. The return
codes from Estimation and Covariance steps (zero for normal termination) are also output.
|
|
Copying
Usage:
|
|
During specific “copying passes” data records are sent to PRED and become accessible. A copying pass is indicated by a positive value of COMACT. At least one copying pass occurs whenever variable values are displayed.
During the first copying pass, COMACT = 1 and MIXNUM = 1. For a mixture model with k subpopulations, COMACT stays at 1 for k passes, while MIXNUM increments from 1 to k. If conditional estimation or the POSTHOC option is used, an additional set of copying passes occurs with COMACT = 2, again with MIXNUM increasing from 1 to k. If no mixture model is used, there are at most two copying passes: one with COMACT = 1 and one with COMACT = 2.
If values of a variable from earlier copying passes are needed in later passes, the values for the variable should be stored in the SAVE region of module NMPRD4. When the values are stored in the SAVE region, that value computed with a given data record during a copying pass will be found in NMPRD4 when the same record is passed during the next copying pass, i.e. it will have been saved from the previous copying pass. This is in contrast to the usual behaviour (with a noncopying pass), where with a given data record, the value in NMPRD4 is the value computed with the previous data record. The value is 0 when a record is passed during the first copying pass, and though PRED may set it or reset it during a subsequent copying pass, this need not be done (see discussion below about COMACT).
The values used in tables and scatterplots (whether or not these values are stored in the SAVE region) are those copied from NMPRD4 with the last copying pass.
A copying block is a block of abbreviated code that is only executed
during a copying pass, i.e. when COMACT has a positive value. Special
rules apply, which allow the user to be less concerned about using the
COMSAV option of the $ABBREVIATED record (see example below):
COM(i) variables that are defined in a copying block are referred to as explicit SAVE variables. PRED-defined variables that are defined in a copying block, other than COM(i) variables, are referred to as implicit SAVE variables. Collectively, the two types of SAVE variables are referred to as SAVE variables. NM-TRAN stores SAVE variables in the SAVE region of module NMPRD4.
Implicit and explicit SAVE variables cannot both appear in abbreviated
code. The COMRES option of the $ABBREV record cannot be used when any
implicit SAVE variables are used, but it must be used when explicit
SAVE variables appear (as whenever COM(i) variables appear).
The size of the SAVE region of NMPRD4 depends on the COMSAV option of
the $ABBREV record. This option may be used in three ways:
- No COMSAV option. The SAVE region of module NMPRD4 will nonetheless include all the SAVE variables.
- COMSAV=n (n>=0). NM-TRAN will, if necessary, extend the size of the SAVE region from n to a larger value so that all SAVE variables will be included in the region.
- COMSAV=-1. There is to be no SAVE region. Variables defined in a copying block will not be SAVE variables.
See COMACT, COMSAV, and PRED-Defined Variables for details.
Consider the following example.
|
|
With the first copying pass the value of COMACT is 1, which signals that during this copying pass, all ETA variables are set to 0. Since the option POSTHOC appears, with a subsequent copying pass the value of COMACT is 2, which signals that during this copying pass, all ETA variables are set to their conditional estimates.
In the example, WR is set to the weighted intra-individual residual. When COMACT=1, the prediction for the typical individual (ETA=0) is computed and stored in FT. FT is a SAVE variable, so this value will have been saved, and when COMACT=2, this same value will be found in FT. With COMACT=2, the weight used with the residual is computed to be the reciprocal of this FT value, while IPRED is computed from conditional estimates of the ETA variables and thus its value applies to to the individual with these estimates, rather than to the typical individual. The values of IPRED and WR appearing in the table are those obtained during the last copying pass. The tabled value of IPRED is based on the conditional estimate of ETA. The value of FT is also the value obtained during the last copying pass, but it in turn is also the value obtained from the first copying pass, as the value of FT has not changed during any subsequent copying pass, and this value is based on ETA=0.
Since FT is a SAVE variable, a SAVE region will have been allocated where this variable will be stored, and (unless there is some reason to use the COMSAV option other than to insure this) the user not be concerned about this option.
Simulation
|
|
A "simulation block" is
executed when ICALL=4 (simulation). Such blocks may be present
in $PK, $ERROR, and $PRED, and may be implemented by means of
generated Fortran subroutines. Special rules:
- No ETA derivatives are computed in a simulation block.
-
Transgeneration is permitted. NM-TRAN allows a data item label to appear on the left of an assignment statement. NM-TRAN generates assignment statements changing first the data item in the event or data record, and then the local variable having that label. E.g., suppose WT is listed in
$INPUT:1IF (ICALL.EQ.4) WT=70+70*ETA(3)The generated code is:
1 2 3 4IF(ICALL.EQ.4.D0)THEN EVTREC(NVNT,8 )=70.D0+70.D0*ETA(03) WT=EVTREC(NVNT,08) ENDIFNONMEM and PREDPP reserved data items should not be modified during simulation. Transgeneration is permitted with simulation with subproblems. With all versions of NONMEM, the data set for each subproblem after the first is the same data set used by the previous subproblem, and includes any changes (transgeneration) made by the previous subproblem.
-
Calls to certain NONMEM routines are permitted:
1 2 3CALL SIMETA(ETA) CALL SIMEPS(EPS) CALL RANDOM(n,R)where n is an integer 1-10. If CALL RANDOM is present, R becomes a reserved variable used for the random number. Note that NM-TRAN provides the necessary calls to SIMETA and SIMEPS in generated routines. Explicit calls are used in abbreviated code only to obtain different values of ETA and EPS.
- A RETURN statement may be used. If in
$ERRORor$PRED, and the RETURN occurs in a simulation block, then Y may be assigned a value prior to the return. If so, then F is set (F=Y); otherwise F is not set. -
Loops are permitted. The syntax is as follows.
1 2 3DO WHILE (condition) .. statements .. END DOFor example, for a truncated normal distribution that only requires testing the eta value directly, this code can be used:
1 2 3 4 5$PK ... DO WHILE (ETA(1).GT.5) CALL SIMETA(ETA) ENDDOAnother example:
1 2 3 4 5 6IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN DO WHILE (ETA(1).GT..5.OR.ETA(1).LT.-.5) CALL SIMETA(ETA) ENDDO ENDIF IF (ICALL.EQ.4) WT=70+70*ETA(1)In the examples, the first random seed of the
$SIMULATIONrecord must have the NEW option. Note also that, because of the previous automatic call to SIMETA, ETA(1) requires no initialization, but that R in the next example does.1 2 3 4 5 6 7IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN R=1 DO WHILE (R.GT..5.OR.R.LT.-.5) CALL RANDOM(2,R) ENDDO ENDIF IF (ICALL.EQ.4) WT=70+70*RThis example illustrates how a categorical variable with equal-likely probabilities can be generated from a random number R, uniformly distributed between 0 and 1. In this example, the categorical variable BIN takes values 1 through 5.
1 2 3 4IF (ICALL.EQ.4) THEN CALL RANDOM(2,R) BIN=INT(R*5)+1 ENDIFThe number 5 can be replaced with any other positive integer n to obtain an n-valued categorical variable. Here INT is the function that transforms a nonnegative number x into the greatest integer not exceeding x. The effect of this simulation code is to perform the transformation:
1 2 3 4 5BIN=1 if R < .2 BIN=2 if R < .4 and R >= .2 BIN=3 if R < .6 and R >= .4 BIN=4 if R < .8 and R >= .6 BIN=5 if R < 1 and R >= .8 -
The "EXIT n k" statement may be used. The value of n may be 0, 1 or 2. The value of k is referred to as the PRED EXIT CODE. If it is desired that the simulation be immediately terminated, then use an EXIT 2 code:
1IF(ICALL==4.and.IPRED<0.1 .and. TIME>20.0) EXIT 2With versions of NONMEM prior to 7.2, the "EXIT 1" statement in the Simulation step also caused NONMEM to abort. As of NONMEM 7.2, if an error occurs in PREDPP during simulation such as PK PARAMETER FOR KA IS NON-POSITIVE or a user-implemented EXIT 1 is issued during simulation, then PRED will be called with a new ETA and EPS. This feature is referred to as Simulation Error Forgiveness. NONMEM describes this as PRED SIMULATION REDO in the NONMEM report file. It writes to the NONMEM report file a description of the data record and THETA and ETA values, for example
1 2 3 4 5 6 7PRED SIMULATION REDO PRED EXIT CODE = 1 INDIVIDUAL NO. 1 ID= 1.00000000000000E+00 (WITHIN-INDIVIDUAL) DATA REC NO. 1 THETA= 3.00E+00 8.00E-02 4.00E-02 ETA= 4.66E-01 2.91E-03 9.95E-01 MESSAGE ISSUED FROM SIMULATION STEPIf ten such errors occur in the same subject, then it is supposed that the cause of the simulation error is not due to an occasional bad random sample, but is caused by a systematic error in the control stream file. The simulation step is terminated with the message
1 2 3PRED ERROR OCCURRED TOO OFTEN ON SIMULATION instead of a message SIMULATION STEP PERFORMEDWith NONMEM 7.5, the PRED EXIT CODE k may be in the range 1000-9999. For example,
1IF(ICALL==4.and.IPRED<0.01 .and. TIME>20.0) EXIT 1 2300This can only occur with user's EXIT code; PREDPP will not generate this kind of EXIT. NONMEM will try PRED SIMULATION REDO up to 10000 times. The message "PRED SIMULATION REDO" itself is written to PRDERR up to 30 times. After that, the following message is written to PRDERR:
1SUBSEQUENT PRED SIMULATION REDO ERROR MESSSAGES SUPPRESSEDNONMEM continues trying new ETA and EPS. Be careful that the condition does not occur too often (causing wasteful computation). After 10000 tries, the simulation is terminated as a protection against an infinite loop. The following message is written to PRDERR:
1TOO MANY CONSECUTIVE PRED ERRORS (>10000) OCCURRED ON SIMULATIONSee PRED Exit code.
As of NM72, if a simulation error occurs (such as “KA nonpositive”), or a user-implemented EXIT 1 is invoked during simulation, then another eta and eps sample set will be generated and tested. If ten such errors occur in the same subject, then it is supposed that the cause of the simulation error is not due to an occasional bad random sample, but is caused by a systematic error in the control stream file, and the simulation is terminated. One can also test a predictive value result and request a new set of ETA and EPS, consider
1 2 3$ERROR … IF(ICALL==4.and.IPRED<0.01 .and. TIME>20.0) EXIT 1 2300Here if the first value following the EXIT statement is 1 (out of a possible range of 0-2), and the second value is between 1000 and 9999 (out of a possible range of 0-9999), then upon the condition being true, NONMEM will try another random eta and eps sample. Be careful that the condition does not occur too often (causing wasteful computation) or that it always occurs due to logic error in the control stream, or NONMEM can be caught in an infinite loop.
If it is desired that the simulation be immediately terminated, then generate an EXIT 2 code:
1IF(ICALL==4.and.IPRED<0.1 .and. TIME>20.0) EXIT 2This will also over-ride the simulation error forgiveness.
Expectation
Usage:
|
|
An expectation block is a block of abbreviated code that is only
executed when ICALL=5. This value of ICALL occurs when the
marginal (MRG_) data item is defined in the data set and has a
non-zero value for some records. Expectation blocks are not required
when the marginal data item is present, but they allow the user
additional functionality. Such blocks may be present in $PRED, $PK,
$ERROR.
If the MRG_ data item has the value 1 in a data record, PRED- (PK- and ERROR-) defined items displayed for the record (e.g. in the row of a table corresponding to the record) are expectations. When ICALL=5, the expectations are being computed. With each call to PRED with the data record, the value being set in Y is contributing to the expectation being computed for the PRED item, and the value being set for a PRED-defined item that will be displayed in a table or scatterplot (except for an item stored in the SAVE region) is contributing to the expectation being computed for that item.
- No ETA derivatives are computed in an expectation block.
-
Calls to certain NONMEM utility routines are permitted in an expectation block:
1CALL RANDOM(n,R)where n is an integer 1-10. If CALL RANDOM is present, R becomes a reserved variable, and may not be used outside the expectation block. Multiple calls to RANDOM may be present.
- A RETURN statement may be used in an expectation block. If Y= appears (i.e. Y is assigned a value) in an expectation block before the RETURN (not necessarily the in same block containing the RETURN), then F is set to Y (F=Y); otherwise F is set to to 0 (F=0). If there is no RETURN statement in the expectation block, then as usual, F is set to the value of Y assigned by the time PRED (PK, ERROR) exits.
-
Loops are permitted in an expectation block. The syntax is as follows.
1 2 3DO WHILE (condition) .. statements .. END DO - If a mixture model is used, then during calls with ICALL=5, both MIXNUM and MIXEST are the index of the subpopulation into which the individual (whose data record is being passed) has been classified.
For an example, suppose that the probability that a particular subject experiences a pain relief score of 2 is computed. Suppose also one wants to compute the (posterior population) expectation of the probability with each of 4 different bolus doses, not all of which are among those used to obtain observations. A fragment of the control file follows.
|
|
A fragment of the data is shown below
|
|
Below is another example that produces a plot of four residuals, formed by the differences between the raw-data-averages and their (posterior population) expectations, versus the doses used to obtain the data.
|
|
data snippet:
|
|
The last example produces a plot of four residuals, formed by the differences between the proportion of subjects in the data set with pain relief score 2 and the (posterior population) expectation of the probability that a subject experiences a pain score of 2, versus the doses used to obtain the data.
|
|
Data snippet:
|
|
In NONMEM v7+ a constant may be up to 30 characters (The length is specified by constant SCO in SIZES). Previous versions limit constants to 12 characters.
It can be used to evaluate factorials:
|
|
With NONMEM VI 2.0, reserved function names are FUNCA through
FUNCC. reserved names for vectors are VECTRA through VECTRC; With
NONMEM 7.3, reserved function names are FUNCA through FUNCI; With
NONMEM 7.4, reserved function names are FUNCA through FUNCZ.
Reserved names for vectors are VECTRA through VECTRZ. Extended
reserved names are also recognized. These are FUNCxy and FUNCxyz,
where each of x, y, z stands for an alphabetic character A-Z,
e.g., FUNCAB or FUNCABC. Similar extended reserved names for
vectors are also recognized: e.g, VECTRAB or VECTRABC. If the
abbreviated code uses one of these extended reserved function names,
but the user does not supply the code via $SUBR OTHER, the NONMEM
executable cannot be created, and there will be an error message
from the Fortran compiler such as:
|
|
Format specification numbers 991 and 992 are used in generated code to avoid conflict with statement numbers arising from DO WHILE statements. The one digit versions are perhaps easier to remember.
No integer format specification is provided because constants are stored as floating point variables in generated and library routines.