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.

1
2
  $PK
  TVCL=THETA(1)

Integers

Integers variables are declared by (see $ABBREVIATED DECLARE for details)

1
  $ABBR DECLARE INTEGER variable_name

A special index integer declared by

1
  $ABBR DECLARE DOWHILE variable_name

must be used for indices of DOWHILE loops. See "Index" section below.

Real vectors

One-dimensional real vector can be defined using

1
$ABBR VECTOR variable_name (dimension)

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) (equivalently OMEGA(2), for diagonal elements);
  • data items defined from the $INPUT record;
  • 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 of DADT in $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 PHI may 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_DATA block (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 for VECTRB, 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 REPLACE feature. 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. (COM is a storage array in module NMPRD4. Even if assigned with a random variables, NONMEM does not compute derivatives of COM() 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):

1
2
3
4
5
6
 $ABBR DECLARE DOWHILE ILOOP $PK
 ILOOP=1
 DOWHILE (condition)
  .. statements ..
 ILOOP=ILOOP+1
 ENDDO

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 $ABBR statement, 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
    7
    
      TERM=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
    16
    
      ILOOP=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:

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.

1
2
3
4
5
6
7
8
9
    IF (condition) THEN
       abbreviated code ...
    ELSEIF (condition) THEN
       abbreviated code ...
    ELSE
       abbreviated code ...
    ENDIF

    IF (condition) assignment statement

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.

1
2
3
4
5
  ;! Valid:
  IF (Q.EQ.(R+C)/D) ...

  ;!Invalid
  IF (Q.EQ.R.AND.(C.GT.D.OR.E.EQ.F)) ...

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:

1
2
3
4
  IF (condition) THEN
  X=...an expression involving a random variable
  X= ....
  ENDIF

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:

1
  IF (WT.GT.0) TVK=THETA(1)*WT

If the condition is false, the non-random variable TVK retains the value set with the previous data record.

1
  IF (WT.GT.0) K=THETA(1)*WT*EXP(ETA(1))

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:

1
2
3
4
5
  IF (WT.GT.0) THEN
    K=THETA(1)*WT*EXP(ETA(1))
  ELSE
    K=K
  ENDIF

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
  K=THETA(1)*EXP(ETA(1))
  IF (TIME.EQ.0) THEN
    OLDA=AMT
    T=TIME
  ENDIF
  A=OLDA*EXP(-K*(TIME-T))
  OLDA=A
  T=TIME

  K=THETA(1)*EXP(ETA(1))
  IF (TIME.EQ.0) THEN
    A=AMT
    T=TIME
  ELSE
    A=A*EXP(-K*(TIME-T))+AMT
  ENDIF
  T=TIME

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:

1
2
3
4
5
6
  TERM=THETA(1)*EXP(ETA(1))
  SUM=0
  DO WHILE(condition)
  SUM=SUM+TERM
  ...
  ENDDO

A product loop such as

1
  PROD=PROD*TERM

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

1
A=FUNCA(X)  ;! similar for FUNCB, FUNCC, etc.

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:

1
2
3
4
   FUNCTION FUNCA(X,X1,X2)
   DOUBLE PRECISION X,X1,X2,FUNCA
   DIMENSION X(9),X1(9),X2(9,9)    ! dimension must be 9.
   ...
  • X: input argument (can be a vector).
  • X1: X1(n) is the first-order partial derivative of the function with respect X(n). If the value of X(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 either X(n) or X(m) will not be a value of a random variable, X2(n,m) need not be set. Nor need any value of X2 be set if a test of MSEC=1 is false (see Partial Derivative Indicators). If the argument is a (scalar) expression, only X2(1,1) may be needed. If the argument is a vector and if the value of X2(n,m) is needed, then the value of X2(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.,

1
 $SUBROUTINES ... OTHER=funcfile

If the reserved function names are used without but not define by $SUBR OTHER, NONMEM will emit error such as:

1
 FUNCA WAS CALLED, BUT NO CODE WAS SUPPLIED.

NONMEM provides reserved variable VECTRA, VECTRB, VECTRC, etc. to be used as the vector argument X, e.g.

1
2
3
4
5
6
7
8
  $PK
  ;#...
  VECTRA(1)=CL
  VECTRA(2)=V
  VECTRA(3)=Q
  VECTRA(4)=V2
  ;#...
  W=FUNCA(VECTRA)

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).

1
 $ABBR FUNCTION function_name(input_vector_name,dimension[,usage])

and define the corresponding Fortran function

1
2
3
4
5
6
7
 FUNCTION function_name(X,X1,X2,NDIM)
 USE SIZES, ONLY: DPSIZE,ISIZE
 INTEGER(KIND=ISIZE) :: NDIM
 REAL(KIND=DPSIZE), INTENT(IN)     :: X
 REAL(KIND=DPSIZE), INTENT(IN OUT) :: X1,X2
 REAL(KIND=DPSIZE):: function_name
 DIMENSION X(NDIM),X1(NDIM),X2(NDIM,NDIM)

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

1
  $ABBR FUNCTION BIVARIATE(VBI,5,3) ;# NDIM=5, usage=3

and use it as

1
2
3
4
5
6
7
8
$PK
;#...
  VBI(1)=RHO
  VBI(2)=5
  VBI(3)=6
  VBI(4)=1
  VBI(5)=1
  BV=BIVARIATE(VBI)

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
  $ABBR FUNCTION BIVARIATE(*,5)
  $ABBR FUNCTION BIVARIATEQ(*,10)
  $ABBR VECTOR VQI(15)
  ;#...
  $PK
    VQI(1)=RHO
    VQI(2)=MX
    BVAL=BIVARIATE(VQI)
    RVAL=BIVARIATEQ(VQI)
    VECTRA(1)=RHO
    VECTRA(2)=MX2
    YVAL=FUNCB(VECTRA)
    QVAL=BIVARIATEQ(VECTRA)

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

1
COMRES=-1

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:

1
2
3
4
5
6
7
  THETA,THETAFR,SETHET,THSIMP,SETHETR,THSIMPR
  OMEGA,OMEGAF,SEOMEG,OMSIMP
  SIGMA,SIGMAF,SESIGM,SGSIMP
  CNTID,IIDX
  CDEN_
  A, A_0                       ! when used in a WRITE or PRINT statement
  ETA, EPS, ERR                ! when used in a WRITE OR PRINT statement

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.,

1
2
3
4
5
   $ABBR DECLARE INTEGER IND
    ...
   $PK
    IND=1
    X=THETA(IND+1)

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 BERNOULLI
 BERNOULLILOGIT
 BINOMIAL
 BINOMIALLOGIT
 BETABINOMIAL
 HYPERGEOMETRIC
 CATEGORICAL
 CATEGORICALLOGIT
 ORDEREDLOGISTIC
 NEGBINOMIAL
 NEGBINOMIAL2
 NEGBINOMIAL2LOG
 POISSON
 POISSONLOG
 MULTINOMIAL
 NORMAL
 EXPMODNORMAL
 SKEWNORMAL
 STUDENTT
 DOUBLEEXPONENTIAL
 LOGISTIC
 GUMBEL
 LOGNORMAL
 CHISQUARE
 INVCHISQUARE
 SCALEDINVCHISQUARE
 EXPONENTIAL
 GAMMA
 INVGAMMA
 WEIBULL
 FRECHET
 RAYLEIGH
 PARETO
 PARETO2
 BETA
 DIRICHLET
 VON MISES

Calling protocol: CALLFL

1
 CALLFL=n
  • In $PK abbreviated code: control when PREDPP calls the PK routine.
  • In $ERROR abbreviated code: control when PREDPP calls the ERROR routine.
  • In $AESINITIAL abbreviated 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
    5
    
    PK 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
    8
    
    PK 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
      2
      
      PK 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
      2
      
      DURING 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
      6
      
      PK 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
      2
      
      DURING 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:

1
2
3
4
   Y=F+ERR(1)
   Y=F*(1+ERR(1))
   Y=F+F*ERR(1)
   Y=F*EXP(ERR(1))

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:

1
  ERROR IN LOG Y IS MODELED

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

1
2
3
 $PK (ONCE PER INDIVIDUAL RECORD)
 $ERROR (ONCE PER INDIVIDUAL RECORD)
 $AESINITIAL (ONCE PER INDIVIDUAL RECORD)

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 $PK record:

    1
    2
    
    (NON-EVENT)
    (ADDITIONAL OR LAGGED)

    NONMEM will output the following messages:

    1
    2
    3
    4
    5
    
    PK 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, $ERROR and $AESINITIAL records (the default):

    1
    2
    
    (EVERY EVENT)
    (EVERY)

    NONMEM will output the following messages:

    1
    2
    3
    4
    5
    6
    7
    
    PK 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 $PK record:

    1
    2
    
    (NEW TIME)
    (NEW EVENT TIME)

    NONMEM will output the following messages:

    1
    2
    
    PK 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 $ERROR record:

    1
    2
    3
    4
    
    (OBSERVATION EVENT)
    (OBS)
    (OBSERVATION ONLY)
    (OBS ONLY)

    NONMEM will output the following messages:

    1
    2
    
    DURING SIMULATION, ERROR SUBROUTINE CALLED WITH EVERY EVENT RECORD
    OTHERWISE, ERROR SUBROUTINE CALLED ONLY WITH OBSERVATION EVENTS
  • Phrases equivalent to CALLFL=1 for the $PK, $ERROR and $AESINITIAL:

    1
    2
    
    (ONCE PER INDIVIDUAL RECORD)
    (ONCE/IND.REC.)

    NONMEM will output the following messages:

    1
    2
    3
    4
    5
    6
    7
    8
    
    PK 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:

1
"      verbatim line

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:

1
2
3
4
5
6
7
"C ITER_REPORT: Iteration number that is reported to output
"C (can be negative, if during a burn period).
"C BAYES_EXTRA, BAYES_EXTRA_REQUEST, used in example 8
" USE NMBAYES_REAL, ONLY: OBJI
" USE NMBAYES_INT, ONLY: ITER_REPORT,BAYES_EXTRA_REQUEST,BAYES_EXTRA
" USE PNM_CONFIG, ONLY: PNM_NODE_NUMBER
" USE NM_INTERFACE, ONLY: TFI,TFD

For example, to use nonmem_reserved_general in $PK, place the file in the present run directory, and do ("examples/example8"):

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
$PK
include nonmem_reserved_general
BAYES_EXTRA_REQUEST=1
MU_1=THETA(1)
MU_2=THETA(2)
MU_3=THETA(3)
MU_4=THETA(4)
CL=DEXP(MU_1+ETA(1))
V1=DEXP(MU_2+ETA(2))
Q=DEXP(MU_3+ETA(3))
V2=DEXP(MU_4+ETA(4))
S1=V1
IF(BAYES_EXTRA==1 .AND. ITER_REPORT>=0 .AND. TIME==0.0) THEN
WRITE(50,*) ITER_REPORT,ID,CL,V1,Q,V2
ENDIF

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
  MODULE MYFUNCS
  contains
  function mymin(a,b,c,d,e)
  integer mymin
  integer a,b,c,d,e
  mymin=min(a,b,c,d,e)
  end function
  function mymax(a,b,c,d,e)
  integer mymax
  integer a,b,c,d,e
  mymax=max(a,b,c,d,e)
  end function
  END MODULE MYFUNCS

One can create file nonmem_reserved_myfunc to declare:

1
" USE myfuncs, only: mymin,mymax

and use it in control stream files:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$PROB  THEOPHYLLINE   POPULATION DATA
$INPUT      ID DOSE=AMT TIME CP=DV WT
$DATA       THEOPP

$SUBROUTINES  ADVAN2 OTHER=myfuncmodule.f90

$PK
;THETA(1)=MEAN ABSORPTION RATE CONSTANT (1/HR)
;THETA(2)=MEAN ELIMINATION RATE CONSTANT (1/HR)
;THETA(3)=SLOPE OF CLEARANCE VS WEIGHT RELATIONSHIP (LITERS/HR/KG)
;SCALING PARAMETER=VOLUME/WT SINCE DOSE IS WEIGHT-ADJUSTED
include "nonmem_reserved_myfunc"
   CALLFL=1
   KA=THETA(1)+ETA(1)
   K=THETA(2)+ETA(2)
   CL=THETA(3)*WT+ETA(3)
   SC=CL/K/WT
I=mymin(1,2,3,4,5.0)
print *,'I ',I

$THETA  (.1,3,5) (.008,.08,.5) (.004,.04,.9)
$OMEGA BLOCK(3)  6 .005 .0002 .3 .006 .4

$ERROR
   Y=F+EPS(1)

$SIGMA  .4

Then compiler will flag errors on mistaken argument use.

EXIT

EXIT statement has three forms:

1
2
3
  EXIT
  EXIT n
  EXIT n k

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

1
2
3
4
5
   WRITE (50,*) 99,ID,CL,THETA(1),ETA(1)

   IF (ICALL.EQ.3) THEN
     WRITE (55,2) BIAS
   ENDIF

and

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
   PRINT list ...
   PRINT *,list ...
   WRITE (unit,format) list ...
   WRITE (*,format) list ...
   WRITE (unit,*) list ...
   WRITE (*,*) list ...
   OPEN(unit)
   OPEN(unit,FILE=filename)
   CLOSE(unit)
   REWIND(unit)

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.,

1
  PRINT *,'A isn''t B'

will output

1
A isn't B

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:

1
2
3
4
5
6
7
      THETA THETAFR SETHET  SETHETR
       THSIMP ETA  THSIMPR
      OMEGA(BLOCK) OMEGA(DIAG) SEOMEG(BLOCK) SEOMEG(DIAG)
      OMSIMP(BLOCK) OMSIMP(DIAG)
      SIGMA(BLOCK) SIGMA(DIAG) SESIGM(BLOCK) SESIGM(DIAG)
      SGSIMP(BLOCK) SGSIMP(DIAG)
      IIDX CNTID IIDX,CNTID

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.)

1
     IF (ICALL.EQ.3) WRITE (99,*) OMEGA(BLOCK),SEOMEG(BLOCK)

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

1
CALL PASS(MODE)

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

1
CALL SUPP(ie,ic)

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

1
CALL RANDOM(n,R)

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

1
2
3
CALL SIMETA(ETA)

CALL SIMEPS(EPS)

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:

1
2
3
  DO WHILE (ETA(1).GT.5)
     CALL SIMETA(ETA)
  ENDDO

RETURN

1
   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 variables PRED_IGNORE_DATA or PRED_IGNORE_DATA _TEST, or the $DATA PRED_IGNORE_DATA option.
  • 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:

1
2
3
4
$PK
IF (A_0FLG.EQ.1) THEN
 ... compartment initialization block ...
ENDIF

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
    3
    
    IF (A_0FLG.EQ.1) THEN
     A_0(1)=THETA(1)*(1+ETA(1))
    ENDIF

    Implicit compartment initialization block:

    1
    
     A_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
    7
    
    IF (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
    ENDIF

    An alternative is to use an indicator variable. E.g., if X is a 0/1 variable, then the above is equivalent to

    1
    
      A_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:

    1
    
      IF (ICALL.EQ.4.AND.A_0FLG.EQ.1) A_0(1)=THETA(1)*(1+ETA(1))

    Instead, use:

    1
    2
    3
    
    IF (ICALL.EQ.4) THEN
      IF (A_0FLG.EQ.1) A_0(1)=THETA(1)*(1+ETA(1))
    ENDIF

    or simply

    1
    2
    3
    
    IF (ICALL.EQ.4) THEN
      A_0(1)=THETA(1)*(1+ETA(1))
    ENDIF

    or even better

    1
    
    IF (ICALL.EQ.4) A_0(1)=THETA(1)*(1+ETA(1))

See also PK subroutine.

Compartment update (NM75)

Usage

1
2
3
4
 $PK
 IF (A_UFLG.EQ.1) THEN
  ... compartment update block ...
 ENDIF

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:

1
2
3
4
5
6
7
8
9
 MTIME(1)=wtime
 MTDIFF=1
 AZTEST=A_0FLG
 IF(TSTATE==MTIME(1).AND.AZTEST==0) A_UFLG=1
 IF(A_UFLG==1) THEN
 A_U(1)=A(1)+wdose
 A_U(2)=A(2)
 A_U(3)=A(3)
 ENDIF

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:

1
2
3
4
 $ERROR
 IF (ICALL.EQ.6) THEN
  ... data average block ...
 ENDIF

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.

1
2
3
4
5
6
  Y=...
  TRDV=DV
  IF (ICALL.EQ.6) THEN
     DV=0
     IF (TRDV.GT.10) DV=1
  ENDIF

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.

1
2
3
4
5
6
7
 Y=...
 TRDV=DV
 IF (ICALL.EQ.6) THEN
    IF (TRDV.LE.2) Y=1
    DV=0
    IF (TRDV.GT.10) DV=1
 ENDIF

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

1
 $OMIT X

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
 $ABB COMRES=4 COMSAV=4
 $ERROR
  ...
 Y=...
 IF (COMACT.EQ.2) THEN
    IF (MIXNUM.EQ.1) COM(1)=ETA(1)
    IF (MIXNUM.EQ.2) COM(2)=ETA(2)
    IF (MIXNUM.EQ.3) COM(3)=ETA(3)
 ENDIF
 IF (ICALL.EQ.6) THEN
    PA1=THETA(1)*TEMPLT(X)**THETA(2)*EXP(COM(1))
    PA2=THETA(1)*TEMPLT(X)**THETA(2)*EXP(COM(2))
    PA3=THETA(1)*TEMPLT(X)**THETA(2)*EXP(COM(3))
    COM(4)=MIXP(1)*PA1+MIXP(2)*PA2+MIXP(3)*PA3
 ENDIF

 $TABLE COM(1) COM(2) COM(3) NOPRINT FILE=junk
 $TABLE ID ... COM(4) ...

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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
 $ERROR
 include nonmem_reserved_general
 Y=...
 IF (COMACT.EQ.2) THEN
    IF (MIXNUM.EQ.1) COM(1)=ETA(1)
    IF (MIXNUM.EQ.2) COM(2)=ETA(2)
    IF (MIXNUM.EQ.3) COM(3)=ETA(3)
 ENDIF
 IF (ICALL.EQ.6) THEN
    PA1=THETA(1)*TEMPLT(X)**THETA(2)*EXP(COM(1))
    PA2=THETA(1)*TEMPLT(X)**THETA(2)*EXP(COM(2))
    PA3=THETA(1)*TEMPLT(X)**THETA(2)*EXP(COM(3))
    COM(4)=MIXPT(1)*PA1+MIXPT(2)*PA2+MIXPT(3)*PA3
 ENDIF

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).

1
2
3
4
 $ERROR
 " USE ROCM_REAL MIXPT=>MIXP_RAW
  ...
 "  COM(4)=MIXPT(1)*PA1+MIXPT(2)*PA2+MIXPT(3)*PA3

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
    3
    
      DO 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:

1
2
3
4
5
6
7
 $INFN
     IF(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 ;Assures no additional computation code in INFN is executed
     ENDIF

Usage (in user-defined function):

1
2
3
 USAGE:
       SUBROUTINE INFN (ICALL,THETA,DATREC,INDXS,NEWIND)
       USE NMPRD_INT, ONLY: PRED_IGNORE_DATA,PRED_IGNORE_DATA_TEST

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
    4
    
    IF(PRED_IGNORE_DATA_TEST==1) THEN
    ...
    RETURN
    ENDIF

    structures 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_DATA is used in the NM-TRAN control stream, then a PRED_IGNORE_DATA pass through the NONMEN data file with PRED_IGNORE_DATA_TEST=1 and ICALL=-1 occurs. Otherwise it does not. Therefore, existing code such as

    1
    2
    3
    
      IF (ICALL<=1) THEN
         ;! ...
      ENDIF

    does 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 IGNORE and ACCEPT options 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
    6
    
    IF(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:

1
2
3
 $PRED
    IF (ICALL.EQ.1) CALL SUPP(0,1)
 ...

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

    1. S1IT (number of current superproblem iteration) equals 1 (or S2IT=1),
    2. S1NUM (number of current superproblem) equals appropriate value, and
    3. 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

      1. S1IT=S1NIT (number of the current superproblem iteration equals total number of superproblem iterations) (or S2IT=S2NIT),
      2. S1NUM (number of current superproblem) equals appropriate value,
      3. IPROB (number of current problem) equals number of last problem in the superproblem, and
      4. 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

      1. S1IT=S1NIT (or S2IT=S2NIT), if there are superproblems
      2. S1NUM equals number of last superproblem, if there are superproblems,
      3. IPROB=NPROB (number of the current problem equals total number of problems), and
      4. 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.,

1
2
3
  IF (ICALL.EQ.1) THEN
   ... initialization block ...
  ENDIF

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
    3
    
         CALL 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
    3
    
         DO WHILE (condition)
    .. statements ..
         END DO

    Here 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
         ENDIF

    This 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
        ENDIF

    DOWHILE (DATA) has the transgeneration statements executed with each data record. In effect, NM-TRAN supplies the statements MODE=... and CALL 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
         ENDIF

    The 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
    2
    
       OMEGA(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
    5
    
        SETHET(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
    2
    
         CALL 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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
  IF (ICALL.EQ.3) THEN
    DO WHILE(DATA)
      IF (NEWIND.LE.1) WRITE (50,*) ETA
    ENDDO
    WRITE (51,*) OBJECT
    WRITE (52,*) THETA
    WRITE (52,*) THETAFR
    WRITE (53,*) SETHET
    WRITE (53,*) SETHETR
    WRITE (54,*) OMEGA(BLOCK)
    WRITE (55,*) SEOMEG(BLOCK)
    WRITE (56,*) SIGMA(BLOCK)
    WRITE (57,*) SESIGM(BLOCK)
    WRITE (58,*) IERE,IERC
  ENDIF

Copying

Usage:

1
  IF (COMACT.EQ.1) TVCL=CL

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.

1
2
3
4
5
6
7
8
 $ERROR
 Y=F+F*EPS(1)
 IPRED=F
 IF (COMACT.EQ.1) FT=F
 WR=(DV-IPRED)/FT

 $EST ... POSTHOC
 $TABLE FT IPRED WR

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

1
2
3
4
5
6
7
8
;# Usage
 IF (ICALL.EQ.4) THEN
  ... simulation block ...
 ENDIF

;# Example
 $PK
  IF (ICALL.EQ.4) CL=THETA(1)+ETA(1)

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:

  1. No ETA derivatives are computed in a simulation block.
  2. 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:

    1
    
    IF (ICALL.EQ.4) WT=70+70*ETA(3)

    The generated code is:

    1
    2
    3
    4
    
    IF(ICALL.EQ.4.D0)THEN
    EVTREC(NVNT,8 )=70.D0+70.D0*ETA(03)
    WT=EVTREC(NVNT,08)
    ENDIF

    NONMEM 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.

  3. Calls to certain NONMEM routines are permitted:

    1
    2
    3
    
    CALL 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.

  4. A RETURN statement may be used. If in $ERROR or $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.
  5. Loops are permitted. The syntax is as follows.

    1
    2
    3
    
    DO WHILE (condition)
     .. statements ..
    END DO

    For 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)
    ENDDO

    Another example:

    1
    2
    3
    4
    5
    6
    
    IF (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 $SIMULATION record 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
    7
    
    IF (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*R

    This 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
    4
    
    IF (ICALL.EQ.4) THEN
      CALL RANDOM(2,R)
      BIN=INT(R*5)+1
    ENDIF

    The 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
    5
    
    BIN=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
  6. 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:

    1
    
    IF(ICALL==4.and.IPRED<0.1 .and. TIME>20.0) EXIT 2

    With 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
    7
    
     PRED 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 STEP

    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. The simulation step is terminated with the message

    1
    2
    3
    
    PRED ERROR OCCURRED TOO OFTEN ON SIMULATION
    instead of a message
    SIMULATION STEP PERFORMED

    With NONMEM 7.5, the PRED EXIT CODE k may be in the range 1000-9999. For example,

    1
    
    IF(ICALL==4.and.IPRED<0.01 .and. TIME>20.0) EXIT 1 2300

    This 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:

    1
    
    SUBSEQUENT PRED SIMULATION REDO ERROR MESSSAGES SUPPRESSED

    NONMEM 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:

    1
    
    TOO MANY CONSECUTIVE PRED ERRORS (>10000) OCCURRED ON SIMULATION

    See 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 2300

    Here 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:

    1
    
      IF(ICALL==4.and.IPRED<0.1 .and. TIME>20.0) EXIT 2

    This will also over-ride the simulation error forgiveness.

Expectation

Usage:

1
2
3
4
 $ERROR
 IF (ICALL.EQ.5) THEN
  ... expectation block ...
 ENDIF

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.

  1. No ETA derivatives are computed in an expectation block.
  2. Calls to certain NONMEM utility routines are permitted in an expectation block:

    1
    
    CALL 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.

  3. 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.
  4. Loops are permitted in an expectation block. The syntax is as follows.

    1
    2
    3
    
       DO WHILE (condition)
        .. statements ..
       END DO
  5. 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.

1
2
3
4
5
6
$INPUT ID DOSE MDV MRG_ ...
$PRED
....
Y = ... ;# likelihood of observation given ETA
$EST METH=COND LAPLACE LIKELIHOOD
$TABLE DOSE

A fragment of the data is shown below

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
 #ID DOSE DV MDV MRG_
  100 5    2  1   1    # PRED item is set to expectation for DOSE=5
  100 10   2  1   1    # PRED item is set to expectation for DOSE=10
  100 20   2  1   1    # PRED item is set to expectation for DOSE=20
  100 40   2  1   1    # PRED item is set to expectation for DOSE=40
  1   3    1  0   0
  1   10   1  0   0
  1   25   2  0   0
  1   30   2  0   0
  2   3    1  0   0
  2   10   1  0   0
  2   25   1  0   0
  2   30   1  0   0
  3   3    1  0   0
  3   10   2  0   0
  3   25   2  0   0
  3   30   3  0   0

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
 $INPUT ID DOSE MDV MRG_ RAW_
 $PRED
  ...
 IF (ICALL.EQ.5) THEN
   Y =... ;# expectation of observation given ETA
 ELSE
   Y =... ;# likelihood of observation given ETA
 ENDIF
 $EST METHOD=COND LAPLACE LIKELIHOOD
 $SCAT RES VS DOSE

data snippet:

1
2
3
4
5
6
7
8
9
 #ID DOSE DV MDV MRG_ RAW_
  100 5    .  1   1    1
  100 10   .  1   1    1
  100 20   .  1   1    1
  100 40   .  1   1    1
  1   5    1  0   0    0
  1   10   1  0   0    0
  1   20   2  0   0    0
  1   40   2  0   0    0

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 $INPUT ID DOSE MDV MRG_ RAW_
 $PRED
  ...
   Y =... ;# likelihood of observation given ETA
   IF (ICALL.EQ.6) THEN
      DVR=DV
      DV=0
      IF (DVR.EQ.2) DV=1
    ENDIF
 $EST METHOD=COND LAPLACE LIKELIHOOD
 $SCAT RES VS DOSE

Data snippet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
 #ID DOSE DV MDV MRG_ RAW_
  100 5    2  1   1    1
  100 10   2  1   1    1
  100 20   2  1   1    1
  100 40   2  1   1    1
  1   5    1  0   0    0
  1   10   1  0   0    0
  1   20   2  0   0    0
  1   40   2  0   0    0
  2   5    1  0   0    0
  2   10   1  0   0    0
  2   20   1  0   0    0
  2   40   3  0   0    0
  3   5    1  0   0    0
  3   10   2  0   0    0
  3   20   2  0   0    0
  3   40   3  0   0    0

1

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.

2

It can be used to evaluate factorials:

1
  exp(gamln(x+1.0)) ;! equals to X! = X(X-1)(X-2)...
3

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:

1
2
Undefined Symbols
_funcaaa_
4

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.

5

No integer format specification is provided because constants are stored as floating point variables in generated and library routines.