# MODEL_PARAMS

A required verbatim section that creates `m[X]` variables for each row of the data set. Taking the previously defined `f[X]`, `r[X]` and `c[X]` as input.

The MODEL_PARAMS section is used in the following scripts:-

- Tut Script
- Gen Script
- Fit Script
- MTut Script
- MGen Script
- MFit Script
- MSim Script

i.e. Any script that defines a mixed effect model.

## Example MODEL_PARAMS section

The example below is used in Fitting a Two Compartment PopPK Model.

    MODEL_PARAMS: |
        m[KA] = f[KA] * exp(r[KA])
        m[CL] = f[CL] * exp(r[CL])
        m[V1] = f[V1] * exp(r[V1])
        m[Q] = f[Q] * exp(r[Q])
        m[V2] = f[V2] * exp(r[V2])
        m[ANOISE] = 0.001
        m[PNOISE] = f[PNOISE]

In the example above the main parameters are defined with the following structure:-

    MODEL_PARAMS: |
        m[X] = f[X] * exp(r[X])

This form ensures that the `m[X]` have a log normal distribution and are therefore constrained to be positive, assuming the `f[X]` input is positive. An alternative formulation is:-

    MODEL_PARAMS: |
        m[X] = f[X] + r[X]

Which means the `m[X]` values have a ~norm() distribution. However if the variance of the `r[X]` is large (relative to `f[X]`) this can result in `m[X]` having negative values sometimes. Often negative values are not physically sensible in PK/PD models (e.g. a negative clearance).

Parameters can also be defined here in terms of `c[X]` values from the data file. For example, if an individual’s weight has an effect on the volume of distribution, it could be defined as:-

    MODEL_PARAMS: |
        m[V] = (f[V] + c[WT]*f[WT_EFF]) * exp(r[V])

Here the `f[WT_EFF]` is an extra parameter to be estimated by PoPy that needs to be defined in the LEVEL_PARAMS section.

Another common pattern in MODEL_PARAMS is the incorporation of IOV `r[X]` variables. This can be done using declarations like:-

    MODEL_PARAMS: |
        m[X] = f[X] * exp(r[X] + r[X_iov])

Where in LEVEL_PARAMS:-

- `f[X]` is typically defined in the first GLOBAL level
- `r[X]` is typically defined in the second INDIV level
- `r[X_iov]` is typically defined in the third IOV level

This is a common pattern in PoPy. It allows the simple combination of `r[X]` from different levels, without using cumbersome and error prone `if` statements. Although you can use `if` statements if you wish. For example a more complex covariate example:-

    if c[GENDER] == "male":
        m[Y] = f[Y_male] * exp(r[Y])
    else:
        m[Y] = f[Y_female] * exp(r[Y])

Here the `c[GENDER]` field from the data file is used as a switch to decide whether to use `f[Y_male]` or `f[Y_female]` for each row as appropriate.

## Static Workspace Variables in MODEL_PARAMS

The MODEL_PARAMS function operates independently on each row of the data file and relies on the LEVEL_PARAMS to arrange the `f[X]` and `r[X]` correctly in each data row (which PoPy handles for you).

However, there may be times when you want a variable’s value to persist from one row to the next. In the MODEL_PARAMS you can explicitly define static workspace variables using the notation `w[X]`. For example:-

    if c[TIME] < 0.0:
        w[PERSISTENT] = 1.0
    else:
        w[PERSISTENT] *= 1.1

This fairly artificial example keeps updating the variable `w[PERSISTENT]` between rows. Here the Python notation ‘*=’ multiplies the variable `w[PERSISTENT]` by itself and the number 1.1. Note by default all variables in PoPy are local, so a naive attempt to do this say:-

    if c[TIME] < 0.0:
        PERSISTENT = 1.0
    else:
        PERSISTENT *= 1.1

Would fail with a Python error, because in the line ‘PERSISTENT *= 1.1’, the local variable ‘PERSISTENT’ has not been previously defined, so can not multiply itself by 1.1.

The `w[X]` notation provides a means of remembering variable values between rows. Note having all variables as static by default (like in Nonmem) is a bad idea as it makes it easier to introduce hard to find coding errors.

## Rules for MODEL_PARAMS section

Like all verbatim sections the MODEL_PARAMS section of the config file accepts free form Python pseudocode, but there are some rules regarding which variables are allowed in a MODEL_PARAMS section as follows:-

- Only new `m[X]` variables and local Python variables can be defined on the left hand side
- `f[X]`, `r[X]`, `c[X]` and `m[X]` are allowed on the right hand side of expressions
- `c[X]` on the right hand side and within `if` statements must be in the data file or defined in the PREPROCESS section, in a Fit Script
- `c[X]` on the right hand side must be defined within the LEVEL_PARAMS in a Gen Script or Tut Script.
- newly declared `m[X]` on the left hand side must have unique names

So you can not use `d[X]`, `p[X]`, `s[X]` or `t[X]` etc variables in this section.

Like all verbatim sections it is possible to introduce syntax errors by writing malformed Python. Any coding errors will be reported by PoPy when attempting to compile or run the MODEL_PARAMS function as a temporary .py file.