NONMEM Users Guide Part IV - NM-TRAN - Chapter IV
IV. Abbreviated Code
IV.A. Introduction
IV.B. General Restrictions
IV.C. Restrictions Specific to an Abbreviated Code for PRED
IV.D. Extensions Specific to an Abbreviated Code for PRED
IV.E. Some Special Right-Hand Quantities
IV.E.1. MIXNUM and MIXEST
IV.E.2. COMACT
IV.E.3. COM( n )
IV.F. PRED-Defined Items
IV.G. PRED Error-Recovery
IV.G.1. Background
IV.G.2. Implementation
IV.H. Pseudo-Statements
IV.I. Verbatim Code

NONMEM Users Guide Part IV - NM-TRAN - Chapter IV

IV. Abbreviated Code

IV.A. Introduction

It can be seen from the example in chapter I that an abbreviated code is much like a FORTRAN code. Indeed, nearly every statement of an abbreviated code is syntactically a FORTRAN statement. The reader is advised to become familiar with very basic FORTRAN coding, in particular the use of assignment statements, conditional statements, arithmetic expressions, and logical expressions. However, not all FORTRAN constructs can be used in an abbreviated code, an abbreviated code does not constitute a complete FORTRAN coded subroutine (this is not a disadvantage), and certain symbols used in an abbreviated code have (semantical) meaning different from standard FORTRAN meaning. For the purposes of developing user-supplied type subroutines for NONMEM, restrictions imposed by abbreviated code (on the use of certain FORTRAN constructs) are not many; usually, use of abbreviated code is quite adequate. The advantages to using an abbreviated code are considerable and outweigh some inconvenience which the restrictions impose.

Nonetheless, one may still want to use FORTRAN statements not allowed in abbreviated code. An escape mechanism is available. Verbatim code can be inserted into abbreviated code. This is FORTRAN code that is itself inserted without change, i.e. verbatim, into the FORTRAN subroutine generated by NM-TRAN (verbatim code can not be used with Library routines). Because this code is essentially not processed by NM-TRAN, other than to copy it into the generated routine, symbolic differentiation is not used with this code. For this and other reasons, verbatim code should only be used by those who understand well how generated subroutines are structured.

The purpose of an abbreviated code is to specify the computation of special quantities called the left-hand quantities

These quantities are symbolized by reserved variables or arrays elements. There are mandatory left-hand quantities and optional left-hand quantities. For each mandatory (optional) left-hand quantity, there must (may) exist some assignment or conditional assignment statement in the abbreviated code that defines the symbol used for the quantity. In the case of an abbreviated code for PRED there is one mandatory left-hand quantity, symbolized by the reserved variable Y, and described below. There are other optional left-hand quantities symbolized by reserved array elements COM(n), which play a minor role; see section E.3.

There are other special quantities called right-hand quantities which can be used in the computation, and these are also symbolized by reserved variables or array elements. The symbols are used in abbreviated code as though they are already defined. These quantities are: the data items of a data record, symbolized by the variables given by the labels and synonyms specified in the $INPUT record; values of the parameters, symbolized by the array elements THETA(1), THETA(2), etc.; values of and variables, symbolized by the array elements ETA(1), ETA(2), ..., ETA(9), ETA(10) and EPS(1), EPS(2), ..., ETA(9), EPS(10); others where noted. (There can be at most 10 ’s and 10 ’s in the model.) The symbols can be used in the right sides of assignment statements and, except for ETA’s, EPS’s, and all other random variables (see below), they can also be used in the right sides of conditional assignment statements and in the conditional expressions of conditional statements. Except where noted, a symbol for a left-hand quantity, once it has been has been defined in abbreviated code, can also be used similarly. Also, variables other than left-hand quantities can be defined by abbreviated code and used similarly. On the other hand, a variable defined by abbreviated code cannot be used as a label in a $INPUT record. This means that quantities cannot be stored into the data record using abbreviated code (see though, section I).

The array elements ETA(1), ETA(2), ..., ETA(9), ETA(10) and EPS(1), EPS(2), ..., ETA(9), EPS(10) can also be regarded as symbolizing the and random variables, not simply values of these variables. For practical purposes, this means that if another variable A is defined in abbreviated code in terms of these elements, then A can be viewed as a function of the and variables, and NM-TRAN generates code or Library instructions to compute various derivatives of A with respect to the and variables. These derivatives are called the - and -derivatives

The variable A itself can be regarded as symbolizing a random variable, so that if it is used to define yet another variable B, the - and -derivatives of B are also computed, and so on. In general, in addition to the and random variables, any variable or array element whose value depends on the value of an or variable is itself regarded as a random variable.†
----------

In the example of chapter I, all variables defined with the string of assignment statements, i.e. the variables KE to Y, are random variables.

The variable Y is (typically) an example of a random variable. If PRED is called with a data record containing an actual observation, Y symbolizes the value of the observation under the statistical model. If PRED is called with a data record with a missing dependent variable data item equal to 1, Y symbolizes a prediction. This prediction, however, is obtainable from the same code used to give the model-based value for the observation, and one need not (although one may) give different code depending on the value of the MDV data item.

A random variable may not be used in the right or left side of a conditional assignment statement. However, an alternative way to code this type of computation is illustrated in section B. A random variable may be used in the conditional expression of a conditional statement, but in this case care should be taken that either the statement is executed only during the Simulation Step (see section D), or that as a result of the expression being true, the EXIT statement is executed (see section G.2).

An abbreviated code is part of an NM-TRAN control record. For example, an abbreviated code for PRED is a part of a $PRED record. The statements comprising the code are contained in one or more continuation records of the control record. However, only one statement can be contained in any one record. A $PRED record along with all its continuation records is called a $PRED block

NM-TRAN comments can be included in an abbreviated code in the usual way, e.g.

Y=THETA(1)*WT+THETA(2)*AGE+ETA(1)   ;linear regression model

Using symbols ’s and ’s, and their counterparts in abbreviated code, the ETA’s and EPS’s, can be confusing. If the data are population data, intraindividual effects are represented by variables, but with single-subject data, they are represented by variables; see section II.C.4. NM-TRAN abbreviated code offers a way to alleviate this confusion. With single-subject data the array element ERR(n) may be used instead of ETA(n); using one has the same effect as using the other. With population data the array element ERR(n) may be used instead of EPS(n). Therefore, in either case one can be safe in always using the symbols ERR(n) to represent the random intraindividual effects.

IV.B. General Restrictions

Each statement may be placed anywhere within positions 1-80 of its containing record. FORTRAN statement continuation may not be used.

Only FORTRAN assignment and conditional statements may be used. FORTRAN statement numbers may not be used.

All variables or array elements are treated as having either type REAL or DOUBLE PRECISION, i.e. as single precision or double precision floating-point numbers, except where noted. Any valid FORTRAN numerical constant can be used, but if it is an integer constant, it is treated as a REAL or DOUBLE PRECISION constant. The choice between REAL and DOUBLE PRECISION is determined by the option value of the the SUBROUTINES option in the $SUBROUTINES record, or by the user’s choice between single and double precision NM-TRAN Library routines. This choice overrides the apparent precision of the constant.

All variable names must be six alphanumeric characters or less, and begin with an alphabetic character. Arrays cannot be defined by the user. (However, names of array elements which are left- or right-hand quantities can appear.) Variable names of exactly six characters, starting with A, B, or C and followed with various combinations of five of the digits 0-9 (e.g. B00003), and the variable name BBBBBB, are reserved for internal use and may not be used in an abbreviated code; see section F.

Use of the exponential operator ** is allowed. However, as with FORTRAN, it is more efficient to use the multiplication operator * when the exponent is a small ( ) integer. FORTRAN library functions LOG (natural logarithm), LOG10, EXP, and SQRT are allowed, but no others.

A subscript must be a positive integer constant.

invalid

I=3
A=THETA(I+2)

valid

A=THETA(5)

Parentheses may not be nested, except when the inner parentheses enclose a subscript.

invalid

A=(THETA(1)+(THETA(2)+C)*2)/E

valid

B=THETA(2)+C
A=(THETA(1)+B*2)/E

As a special case: parentheses may not be used within logical expressions.

invalid

IF (Q.EQ.(R+C)/D) A=3

valid

B=R+C
IF (Q.EQ.B/D) A=3

As another special case: parentheses may not be used within an expression for an argument of a FORTRAN library function.

invalid

A=EXP(-(THETA(1)+C)*TIME)

valid

B=THETA(1)+C
A=EXP(-B*TIME)

On the other hand,

valid

A=EXP(-THETA(1)*TIME)

Conditional statements may not be nested. In particular, an ELSE IF clause may not be used.

invalid

A=THETA(3)
IF (Q.EQ.1) THEN
   A=THETA(1)
   IF (R.NE.B) A=A+THETA(2)

ENDIF

valid

A=THETA(3)
IF (Q.EQ.1.AND.R.EQ.B) A=THETA(1)
IF (Q.EQ.1.AND.R.NE.B) A=THETA(1)+THETA(2)

An IF-ENDIF block must be completely within a contiguous block of the NM-TRAN record containing the abbreviated code.

invalid

$PRED
   IF (A.EQ.B) THEN
      Y=W1

$PRED

   ELSE
      Y=W2
   ENDIF

valid

$PRED
   IF (A.EQ.B) THEN
      Y=W1
   ELSE
      Y=W2
   ENDIF

Once a random variable is defined it cannot be redefined:

invalid

A=TVV+TVV*ETA(2)
A=A+THETA(4)

valid

B=TVV+TVV*ETA(2)
A=B+THETA(4)

Random variables cannot appear in the right or left sides of conditional assignment statements.

invalid

IF (Q.EQ.1) A=THETA(1)*(1+ETA(1))
IF (Q.EQ.0) A=THETA(2)*(1+ETA(1))

valid

IF (Q.EQ.1) B=THETA(1)
IF (Q.EQ.0) B=THETA(2)
A=B*(1+ETA(1))

invalid

IF (Q.EQ.1) A=THETA(1)*(1+ETA(1))
IF (Q.EQ.0) A=THETA(2)*(1+ETA(2))

valid

B1=THETA(1)*(1+ETA(1))
B2=THETA(2)*(1+ETA(2))
A=Q*B1+(1-Q)*B2

A variable on the left side of an assignment statement should not also be used on the right side if the assignment redefines the variable to be a random variable.

invalid

A=THETA(1)
A=A*EXP(ETA(1))

valid

A=THETA(1)*EXP(ETA(1))

valid

B=THETA(1)
A=B*EXP(ETA(1))

IV.C. Restrictions Specific to an Abbreviated Code for PRED

There are further restrictions specific to each type of abbreviated code. For an abbreviated code for PRED, certain variables which occur as arguments to the PRED subroutine may not be used. Theses are DATREC, INDXS, G, and H. The variable F can be used; it has no special meaning in the code.

IV.D. Extensions Specific to an Abbreviated Code for PRED

Extensions specific to each type of abbreviated code can exist. For an abbreviated code for PRED, certain reserved variables may be used to symbolize some special right-hand quantities. These variables, ICALL and NEWIND, occur as arguments to the generated PRED subroutine. They are now described.

The variable ICALL has the value 0 if the call to PRED is the first call to PRED in the run (the run initialization call). It has the value 1 if the call to PRED is the first call to PRED in the problem (a problem initialization call). It has the value 3 if the call to PRED is the last call to PRED in the problem (a problem finalization call). It has the value 2 if the call to PRED is a regular call during data analysis, and the value 4 if the call is a regular call during data simulation. At initialization and finalization calls the data items occuring as right-hand quantities are those of the first data record. At the run initialization call the THETA’s are 0. At a problem initialization (finalization) call, the THETA’s are the initial (final) estimates. During an initialization (finalization) call, the ETA’s are 0 (0, or conditional estimates for the first individual if conditional estimates have been requested).

The variable NEWIND has value 0 if the data record is the first record of the data set. It has the value 1 if the data record is the first data record of the second or subsequent individual record. It has the value 2 if the data record is the second or subsequent data record of an individual record. With single-subject data individual records are defined in such a way that data records are contained in a number of different individual records; see section II.C.4.1. Therefore, except when the data record is the first data record of the data set and the value of NEWIND=0, the value of NEWIND can be 1 or 2.

IV.E. Some Special Right-Hand Quantities

Certain reserved variables listed in NONMEM read-only commons (and available to any subroutine for which an abbreviated code may be given) may be used in abbreviated code to symbolize some special right-hand quantitites. These are now described. They are intended for use in advanced NONMEM applications. This section may be ignored by beginning NONMEM users.

IV.E.1. MIXNUM and MIXEST

The variable MIXNUM can be used when a mixture model is used. With a mixture model there are one or more submodels that can be used to describe an individual’s data. PRED (PK, ERROR, etc. if PREDPP is used) must be able to compute its outputs under each of these submodels. However, with each call to the routine, the outputs are computed only under one submodel. With data from a given individual’s record, and when ICALL=2 or 4, MIXNUM is the number of the submodel of the mixture that should be used to obtain the outputs. The submodels are enumerated 1, 2, ..., m, where m is the number of possible submodels that can be used to describe the individual’s data, a number returned in an argument of the routine MIX; see Guide VI, section III.L.2. The number m can vary between individual records. When ICALL=1 or 3, MIXNUM is 1.

The variable MIXEST can be used when a mixture model is used. With data from a given individual’s record, and when ICALL=3, MIXEST is the number of the submodel of the mixture that "best" describes the individual’s data. The best submodel is selected according to a Bayesian computation, conditional on the individual’s data and on the final estimates of the population parameters. When ICALL=1, 2, or 4, MIXEST is 1.

IV.E.2. COMACT

The variable COMACT can be used to identify those calls to the routine with which PRED-defined items (see section F) are obtained by NONMEM for the purpose of displaying these items in tables and scatterplots. COMACT is 1 or 2 with such calls; otherwise it is 0. There are (up to) two sets of calls with the data records of an individual record. With ETA’s set to 0, there is a first set of calls. If conditional estimates are requested, then with ETA’s set to these estimates, there is a second set of calls. If a mixture model is used, with each value of MIXNUM (see section E.1) there are more than two sets of calls. With ETA’s set to 0, there is a set of calls for each distinct value of MIXNUM. If conditional estimates are requested, then with ETA’s set to these estimates, there is a set of calls for each distinct value of MIXNUM. When the ETA’s are 0, COMACT is 1. When the ETA’s are conditional estimates, COMACT is 2.

PRED-defined items are stored in variables defined in PRED (PK or ERROR if PREDPP is used) (see section F). Normally, these items may change from call to call. That is, at one call an item is computed and stored in a variable V; then it is available in V at the start of the subsequent call; at that call, though, another item may be computed and stored in V. Therefore, if an item is computed at a call with a particular data record (of the individual record) when COMACT=1, it may no longer be available at a call with the same data record when COMACT=2, due to there being (in general) multiple calls to PRED (PK and ERROR) with different data records of the individual record between and . There are, however, situations where it is desired that the item be available at . This problem is solved by making a special use of NONMEM read-only common NMPRD4.

Items may change from call to call whether they are stored in a locally defined variable or in a globally defined variable listed in common NMPRD4 (see sections III.B.16-17). However, an initial section of NMPRD4 can be identified to NONMEM as the save region All items stored in this region at a call to PRED (PK or ERROR) with a particular data record when COMACT=1 are available at a call with the same data record when COMACT=2. In fact, with mixture models in mind, if at any call to PRED (PK or ERROR) with a particular data record (when COMACT=1 or 2 and MIXNUM has any value), an item is stored in a variable listed in the save region, then the item is available at any subsequent call with the same data record (when COMACT=1 or 2 and MIXNUM has any value).

The save region of NMPRD4 is comprised of the first positions, where is the integer given with the COMSAV option on the $ABBREVIATED record (see section III.B.7). If the option is omitted, or if is 0, there is no save region. The way to store an item in a variable listed in the save region is described in the next section.

IV.E.3. COM( n )

There are additional right-hand quantities symbolized by the array elements COM(n)

The nth element refers to the nth item stored in common NMPRD4. These quantities are useful when a user-supplied routine has stored items in this common, and these items are to be used by abbreviated code. Typically, the first positions of NMPRD4 are reserved to allow user-supplied routines to store PRED-defined items in these positions so that they may be displayed in tables and scatterplots (see section III.B.16). The integer n must not exceed the integer , where is the integer specified with the COMRES option on the $ABBREVIATED record (see section III.B.7). Even if the computation of COM(n) depends on ’s or ’s, COM(n) is not regarded as a random variable. That is, - and -derivatives of COM(n) are always 0, but never actually computed.

PRED-defined items defined by abbreviated code can also be stored in the first positions, since the array element COM(n) can function as an optional left-hand quantity. This can facilitate the communication in both directions between a user-supplied routine and a routine specified by abbreviated code. It can even be used to allow two-way communication between two abbreviated codes. (Regular variables used on the left in one abbreviated code cannot be used on the left in another abbreviated code, as long as variables are listed in NMPRD4, but see sections H and III.B.7.) Another use of these left-hand quantities is to allow abbreviated code to specify that an item be stored in the save region of NMPRD4 (see section E.2). The rule given above still holds: COM(n) is not regarded as a random variable. This means that while COM(n) may have a value that depends on ’s and ’s, the - and -derivatives of COM(n) are always 0. This in turn implies that abbreviated code cannot define a random variable to be listed in the save region of NMPRD4. The rule also means that COM(n) may be computed in a conditional assignment statement even though its values depend on random variables.

IV.F. PRED-Defined Items

The values of a variable defined in a user-supplied PRED or in an abbreviated code for PRED is called a PRED-defined item. For the purpose of this definition, PREDPP is not considered to be either type of PRED specification. However, for documentation purposes, the values of a variable defined in a user-supplied routine used by PREDPP, or in an abbreviated code for such a routine is also called a PRED-defined item. If, for example, the routine is PK, such a value is also called a PK-defined item

PRED-defined items can be displayed in tables and scatterplots; see sections III.B.16-17.

The definition of a variable in an abbreviated code can generate additional definitions of other variables, called generated variables appearing in the generated code or the Library routine, but not appearing in the abbreviated code. The names of generated variables are all six characters long. Certain generated variables symbolize the values of partial derivatives and are normally listed in NMPRD4 so that their values can be displayed like other PRED-defined items. For the PRED subroutine, the names of these variables, and the four character labels used in tables and scatterplots for the values of these generated variables, are now described. For the subroutines of PREDPP, they are described in sections V.C.5,6,7,9.

Variables which symbolize (first-, second-, mixed-) partial -derivatives of random variables defined in abbreviated code for PRED (first- and second-partial -derivatives of random variables defined in abbreviated code for PK if PREDPP is used) are generated and displayable. They have names A....., where the dots stand for various combinations of five digits 0-9. The values of variables A00... and A01..., in particular, are labeled 0... and 1..., respectively. E.g. The values of A01458 are labeled 1458. The label for the values of a variable A02..., or higher, is the first four characters of the variable name. E.g. The values of A05677 are labeled A056.

Variables which symbolize first-partial -derivatives of random variables defined in abbreviated code for PRED (ERROR if PREDPP is used) are displayable. They have names C....., where the dots stand for various combinations of five digits 0-9. The values of variables C00..., in particular, are labeled 2... in tables and scatterplots. E.g. The values of variable C00123 are labeled 2123. The label for the values of a variable C01..., or higher, is the first four characters of the variable name. E.g. The values of C05677 are labeled C056.

It is not possible to know what variable symbolizes a given partial derivative without first obtaining and inspecting the generated subroutine. Comment lines in the code describe the correspondence. The name for the variable can be used in a $TABLE or $SCATTERPLOT record of a subsequent run (provided the abbreviated code is the same in that run).

IV.G. PRED Error-Recovery

PRED may exit with a nonzero PRED error return code. This section describes how to implement such an exit with abbreviated code. It describes the ABORT and NOABORT options used in the $THETA and $ESTIMATION records.

IV.G.1. Background

When PRED exits with a nonzero PRED error return code, either the NONMEM run is immediately aborted or an error-recovery procedure is implemented. An error-recovery procedure entails continued calls to PRED, but with values for the THETA’s or ETA’s different from those with previous calls which resulted in nonzero return codes. There are two error-recovery procedures: one with which different values for ETA’s are tried, the ETA-recovery a second with which different values for THETA’s (and possibly ETA’s) are tried, the THETA-recovery

Whenever it is possible to implement the ETA-recovery, this is done. If this procedure fails, or if it is not possible to implement the ETA-recovery, and the error return code is obtained during either the search in the Estimation Step or the search in the Initial Estimation Step, then a choice exists between an abort and implementation of the THETA-recovery. If the THETA-recovery fails, or if it is not actually possible to implement the THETA-recovery, the NONMEM run is aborted.

A PRED error return code can have values 0, 1, or 2. The value 0 means that the return is a normal return. The value 1 means that if the choice exists between an abort or implementation of the THETA-recovery, then this choice is to be made using control stream information. The value 2 means that if the choice exists between an abort or implementation of the THETA-recovery, then the abort should be chosen.

When an abort occurs, an error message will appear in the NONMEM output, in the intermediate output file (if such a file exists), and in the PRED Error file. When the THETA-recovery is implemented, an error message appears in the intermediate output file (if such a file exists), in the PRED Error file, and if recovery is not possible, in the NONMEM output. The error message is called a PRED error message

When the PRED error return code is 1, and a choice exists between implementation of the THETA-recovery and an abort, the THETA-recovery is implemented if the NOABORT option is used on the $ESTIMATION ($THETA) record. If the NOABORT option is not used, then the run is aborted. Often, the most appropriate response to an abort occuring during the Initial Estimate Step, or during the Estimation Step after the 0th iteration summary has been output, is to rerun the problem requesting that the THETA-recovery procedure be implemented. Warning: If the NOABORT option is used before an actual abort has occured, be sure to check the PRED Error file for possibly useful diagnostic information that is otherwise available in NONMEM output when an abort occurs.

More information about PRED error-recovery may be obtained by consultation with the NONMEM Project Group.

IV.G.2. Implementation

An quick exit from PRED with a nonzero return code can be implemented in abbreviated code for PRED (or in abbreviated code for PK, or ERROR, in which case the exit is from PREDPP) with this statement:

EXIT n k

where n is the return code (1 or 2) and k is a user code (1-999). If the user code is used, it can be any value the user wishes in the indicated range. In this case a part (shown here) of the PRED error message gives the user code:

PRED SUBROUTINE: USER ERROR CODE =   k

The user code can be omitted. If it omitted, then the return code too can be omitted, and then the return code is 1 by default. The EXIT statement can be used with an IF statement or within an IF-ENDIF block, e.g.

IF (CL.LE.0)  EXIT 1 2

IV.H. Pseudo-Statements

A pseudo-statement is a statement of abbreviated code of the form of an (unconditional) assignment statement, i.e. A=B, where A is a specific reserved variable, and B is an integer constant. The variable A symbolizes a type of left-hand quantity, but, unlike other such quantities, it cannot be used as a right-hand quantity. The variable characterizes the type of the pseudo-statement. There are different types of pseudo-statements specific to each type of abbreviated code. There is usually a restriction on the permitted values for the integer B. Each type of pseudo-statement can appear only once in an abbreviated code for a particular routine. It must appear before other statements of abbreviated code ocurring in that routine.

For an abbreviated code for PRED, there is only one allowable type of pseudo-statement. The variable is COMRES, and the only permitted value for the integer constant is -1. So, the statement must look like

COMRES=-1

If this statement appears, then no variables defined in the abbreviated code are listed in the common NMPRD4. In this regard, see also the discussion of the option COMRES=1 in section III.B.7. With an abbreviated code for PRED (where no additional abbreviated code for another routine can also be used), the effect of the above pseudo-statement is identical to use of that option.

IV.I. Verbatim Code

As mentioned in section IV.A, verbatim code should be used only by those who understand well how generated codes are structured. Verbatim code is FORTRAN code which may be inserted into abbreviated code. This code is in turn inserted unchanged, i.e. verbatim, into the generated subroutine. NM-TRAN does not generate code for the computation of - and -derivatives based on verbatim code, so particular care in using verbatim code is needed when variables which are interpreted as random variables in abbreviated code are used in verbatim code.†
----------

NM-TRAN does not check whether verbatim code uses correct FORTRAN syntax; this check will be made by the FORTRAN compiler. NM-TRAN Library subroutines can not be used when verbatim code is used. A portion of abbreviated code which includes verbatim code might look like:

IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN
" 5 IF (ABS(ETA(2)).GT.5) THEN
"      CALL SIMETA (ETA)
"      GO TO 5
"   ENDIF
ENDIF

Neither the use of the absolute value function, a subroutine call, the use of a statement number, nor a GO TO are FORTRAN constructs which are allowed in abbreviated code. Essentially, any line whose first nonblank character is a double quote is recognized as containing verbatim code. The double quote is dropped, and the remaining (up to 79) characters of the line are copied to the generated code. For the user’s convenience, verbatim code following a statement number is adjusted so that it conforms to FORTRAN conventions regarding where FORTRAN code is placed in a line; see more discussion of this below. This means that in the example the text after the 5 is moved so that it begins in position 7 of the generated line; see the generated code below. There is a leading blank before the 5. As with all FORTRAN statements with statement numbers, a statement number can be placed anywhere in positions 1-5. A single line of verbatim code, other than a FORTRAN comment statement (see below), may be copied to more than one line of generated code if NM-TRAN determines that the characters of the generated line would otherwise extend beyond position 72; FORTRAN continuation lines are created as necessary to limit each generated line to 72 characters.

In the above example, by default the verbatim code is placed in the generated subroutine after some initial executable code required for routine initialization purposes; see below. This initial code contains a call to SIMETA to obtain simulated values of the ETA’s. The effect of the verbatim code is to replace the value of ETA(2) with a value less than 5 in absolute value if necessary. For this code to have the desired effect, the option NEW must be used in the $SIMULATION record.

In actuality, NM-TRAN does modify verbatim code. It has already been seen that a placement adjustment takes place. However, perhaps more surprisingly, certain variables occuring in verbatim code are replaced by certain array elements. To see how this happens, recall that a variable that is a label for data items of a particular type can be used freely in abbreviated code. The mechanism by which this is allowed does not by itself generally imply that this same variable can be used freely in verbatim code. For example, the abbreviated code

A=THETA(2)*WT*EXP(ETA(2))

can generate the FORTRAN code

      WT=DATREC(05)
      B00001=DEXP(ETA(02))
      A=THETA(02)*WT*B00001

which defines WT and then uses this variable. The definition is given in terms of a reference to the DATREC array where the weight data item is to be found. This array is defined as an argument to the generated routine. The analogous verbatim code

" A=THETA(2)*WT*EXP(ETA(2))

copied without change into generated code, contains an undefined variable (WT) if the variable WT is not used in abbreviated code. To avoid this difficulty, any instance of a variable that is a label for data items and that is used in verbatim code is replaced with a reference to the DATREC array (EVTREC array if PREDD is used). Therefore, the above verbatim code is actually translated into

      A=THETA(2)*DATREC(05)*EXP(ETA(2))

This rule is called the replacement rule It applies as well to instances of the variable occuring on the left of an assignment statement. This enables data items to be transgenerated during a Simulation Step (e.g. see section III.B.13, and Guide VI, Figure 2 along with the accompanying discussion in section III.L.1). The rule applies to essentially all instances wherever they appear. Because of the replacement rule, a more accurate name for verbatim code might be quasi-verbatim code.

Implementation of the replacement rule is most often helpful to the user. However, if truly verbatim code, i.e. nonmodified code, is desired, there is a way to obtain it. This involves using the character ’@’ as an "escape" character. If the escape character is used immediately before an instance of the variable, the variable is not replaced. For example, if the verbatim code is

" A=THETA(2)*@WT*EXP(ETA(2))

then the generated code is

      A=THETA(2)*WT*EXP(ETA(2))

This same generated code can be obtained with the verbatim code

"@ A=THETA(2)*WT*EXP(ETA(2))

If the escape character is used immediately after the double quote, the entire line is copied without change, except that the double quote and escape characters are deleted.

NM-TRAN comment lines are not copied to the generated code. A FORTRAN comment statement can be inserted into the generated routine. Here is an example:

"C this line is used at debug time

If the character immediately following the double quote is either C’, ’c’, ’*’, or ’"’, the line is recognized to be a comment statement. The 79 characters following the double quote are copied without change into positions 1-79 of the generated line. Notice that lower case can be used in verbatim code. However, lower case is converted to upper case before the replacement rule is applied.

As mentioned above, and as seen from some examples, verbatim code is adjusted so that it conforms to FORTRAN conventions regarding where FORTRAN code is placed in a line. Alphabetic text that "starts" a line of verbatim code or that follows a statement number is adjusted so that it begins in position 7 of the line of generated code, unless the line is recognized to be a FORTRAN comment line.†
----------

FORTRAN continuation lines can be expressed with verbatim code. There are two ways to do this.††
----------

1.

Blanks occur in positions 1-5 and a non-blank in position 6. This conforms to usual FORTRAN syntax. Therefore, the following variation of the first example above will cause a problem:

IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN
" 5 IF (ABS(ETA(2)).GT.5) THEN
"     CALL SIMETA (ETA)
"     GO TO 5
"   ENDIF
ENDIF

because the second and third statements of the verbatim code appear to the compiler as continuation lines.

2.

The ampersand character ‘&‘ appears somewhere in position 1-5. Then the ampersand character is deleted and the character ’X’ is placed in position 6 of the generated line. The remainder of the line is adjusted to follow the ’X’.

It is not obvious where exactly verbatim code is placed in the generated code since the user is not excercising strict control over the latter. However, some control over where verbatim code is placed is available. A generated subroutine has four sections.

First section: nonexecutable declaration statements

Second section: executable code required for initialization purposes

Third section: code implementing abbreviated code

Fourth section: code that stores subroutine outputs

RETURN statement.

Verbatim code can be specifically placed immediately after the first section, throughout the third section, or immediately after the fourth section (prior to the RETURN statement). Verbatim header statements are used for this purpose.

Verbatim code that is to go immediately after the first section must precede all abbreviated code and must be immediately preceded by the header statement

"FIRST

Spaces before or after the word FIRST are permitted. No abbreviated code may precede "FIRST except for pseudo-statements. NM-TRAN comment lines may precede "FIRST. This block of verbatim code is called the FIRST block. FORTRAN requires that all declarations precede all executable statements, so declarations must be placed in this block.

Verbatim code that is to be placed throughout the third section can be preceded by the header statement

"MAIN

Consider this variation of the first example of verbatim code from above.

"MAIN
IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN
" 5 IF (ABS(ETA(2)).GT.5) THEN
"      CALL SIMETA (ETA)
"      GO TO 5
"   ENDIF
ENDIF

Spaces before or after the word MAIN are permitted. No abbreviated code may precede "MAIN except for pseudo-statements. NM-TRAN comment lines may precede "MAIN. The lines of verbatim code that go into the third section need not be contiguously placed within the abbreviated code as they are in this example. Verbatim code may be intermingled with abbreviated code. A line of verbatim code that follows a line L of abbreviated code is copied to the generated code following all generated code implementing L. There may be abbreviated code preceding the first verbatim code that goes into the third section, as in this example. Then "MAIN may be omitted; by default this first verbatim code goes into the third section.

Suppose the first verbatim code that is to go into the third section precedes all lines of abbreviated code. If there is a FIRST block, then "MAIN is necessary. In this case "MAIN acts a delimiter, ending the FIRST block. Without it, this verbatim code would appear to belong to the FIRST block.

Consider this extension of the previous example

"FIRST
" REAL R
"MAIN
IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN
" 5 IF (ABS(ETA(2)).GT.5) THEN
"      CALL SIMETA (ETA)
"      GO TO 5
"   ENDIF
"   ETAS1=ETA(1)
"   ETAS2=ETA(2)
"   CALL RANDOM (2,R)
"   WT=70+7*R
"   @WT=WT
"   WGHT=WT
ENDIF
"   IF (ICALL.EQ.4) @WT=WGHT

Since the number returned in R by the NONMEM utility routine RANDOM is always a single-precision number (see section III.B.13), and since the FORTRAN declaration statement IMPLICIT DOUBLE PRECISION appears in a generated code whenever double precision is the choice made with the $SUBROUTINES record, the declaration REAL R needs to be added. Since declarations must precede executable code, the declaration is included in the FIRST block. As with the previous example, the statement "MAIN may be omitted. However, with this variation

"FIRST
" REAL R
"MAIN
" IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN
" 5 IF (ABS(ETA(2)).GT.5) THEN
"      CALL SIMETA (ETA)
"      GO TO 5
"   ENDIF
"   ETAS1=ETA(1)
"   ETAS2=ETA(2)
"   CALL RANDOM (2,R)
"   WT=70+7*R
"   @WT=WT
"   WGHT=WT
" ENDIF
"   IF (ICALL.EQ.4) @WT=WGHT

"MAIN serves as a necessary delimiter of the FIRST block. The verbatim code just shown is discussed in greater detail at the end of this section.

Verbatim code that is to go immediately after the fourth section should be immediately preceded by the header statement

"LAST

Spaces before or after the word LAST are permitted. If this statement is used, it, and the contiguous lines of verbatim code that follow it, must be placed at the very end of the abbreviated code (one can ignore the presence of NM-TRAN comment statements). These lines of verbatim code, the LAST block, are placed altogether, immediately before the RETURN statement of the generated routine.

Generally, a line of verbatim code that is not in a FIRST block, and not in a LAST block, goes into the third section of generated code by default, whether or not the statement "MAIN actually appears.

For certain subroutines (e.g. DES), the ability to use certain verbatim header statements does not exist, or if a header statement can be used, it has no effect. Descriptions of these particular cases are included with the descriptions of each of the different abbreviated codes.

The presence of verbatim code anywhere in an abbreviated code has two useful side effects.

The generated code then includes needed declarations for all reserved variables that can be used in the abbreviated code. (When verbatim code is not present, only declarations for those reserved variables used in the abbreviated code are included.) Hence any reserved variable may be used in verbatim code without the need to also include declarations for it in verbatim code.

Lines of abbreviated code that follow some verbatim code may then include variables that are not defined in the abbreviated code preceding the verbatim code. Normally, the presence of an undefined variable is considered to be invalid, and this raises an error. When verbatim code is present, this restriction is relaxed since the variable may have been defined in the verbatim code.

A variable defined by verbatim code is implicitly a double or single precision variable according to the choice made with the $SUBROUTINES record. This implicit declaration can be overridden with an explicit type declaration in the FIRST block.

In the remainder of this section some verbatim code shown above is examined in greater detail.

"FIRST
" REAL R
"MAIN
" IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN
" 5 IF (ABS(ETA(2)).GT.5) THEN
"      CALL SIMETA (ETA)
"      GO TO 5
"   ENDIF
"   ETAS1=ETA(1)
"   ETAS2=ETA(2)
"   CALL RANDOM (2,R)
"   WT=70+7*R
"   @WT=WT
"   WGHT=WT
" ENDIF
"   IF (ICALL.EQ.4) @WT=WGHT

In this example ETAS1 and ETAS2 are the labels for data items, and by the replacement rule, these items become the simulated values of and . (During the Simulation Step, transgeneration of data items is allowed. Transgenerated items are stored in NONMEM’s internal copy of the data set.) Weights are also simulated (normally distributed values with mean 70Kg and standard deviation 7Kg if the option NORMAL is used in the definition of the second random source). WT also is a data item label, and so weights are stored as transgenerated data items. Since weight is used in subsequent computations in abbreviated code, the variable WT is defined in the second section of generated code, but as being equal to the weight in the data record as that record appears when the second section of code is executed. Since the subsequent computations should involve transgenerated weight, WT is redefined after the transgeneration, using the escape character. Notice that weight is simulated only with the first data record of the individual record, and that it is stored as a transgenerated item only with this first data record. Its value, though, may be needed in computations during the Simulation Step with each of the data records of the individual record. WGHT is a PRED-defined item, not a data item label. Its value in all these data records remains unchanged from the value to which it is set with the first data record. So, WGHT is given the simulated value, and with each data record, WT is redefined to be this value, again using the escape character. Were WGHT not used, the value of WT with any data record other than the first record would be the data item in that record.

This strategy works if only simulation is implemented (indeed, if the ONLYSIMULATION option is used in the $SIMULATION record). However, if data analysis is also implemented, then unless further steps are taken, a problem arises when the routine is called with a data record other than the first data record of an individual record. This is because the simulated weight value is only stored in the first data record. Here is another variation of the same verbatim code, achieving the identical effect, but also addressing this problem.

"FIRST
" REAL R
" IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN
"    CALL RANDOM (2,R)
"    WT=70+7*R
"    WGHT=WT
" ENDIF
" IF (ICALL.EQ.4) WT=WGHT
"MAIN
" IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN
" 5 IF (ABS(ETA(2)).GT.5) THEN
"      CALL SIMETA (ETA)
"      GO TO 5
"   ENDIF
"   ETAS1=ETA(1)
"   ETAS2=ETA(2)
" ENDIF

Here weight is simulated immediately after the declarations, before the second section, and because of the replacement rule, it is stored in the data record. Therefore, when WT is redefined in the second section, it is given this value. This is true with the first data record of the individual record, and by virtue of the use of WGHT, it is also true with subsequent data records. However, in this variation the escape character does not need to precede WT with the statement WT=WGHT, since it is not the variable itself that needs to be redefined; that happens subsequently in the second section. Rather, the data item needs to be transgenerated, so that when the variable is redefined, the variable is defined to be the transgenerated value. As a result, with this variation, the transgeneration takes place with all data records, whereas with the previous variation the transgeneration only takes place with the first data record of the individual record.

Here is yet a simpler variation.

"FIRST
" REAL R
" IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN
"    CALL RANDOM (2,R)
" ENDIF
" IF (ICALL.EQ.4) WT=70+7*R
"MAIN
" IF (ICALL.EQ.4.AND.NEWIND.NE.2) THEN
" 5 IF (ABS(ETA(2)).GT.5) THEN
"      CALL SIMETA (ETA)
"      GO TO 5
"   ENDIF
"   ETAS1=ETA(1)
"   ETAS2=ETA(2)
" ENDIF

TOP
TABLE OF CONTENTS
NEXT CHAPTER ...