# Generate BLQ observations and fit different error models¶

In this example we will demonstrate generating and fitting to **BLQ** data using the ~rectnorm() distribution with a simple depot + one compartment model as follows:-

Note

See the Depot + One compartment PK with BLQ obtained by the PoPy developers for this example, including input script and output data file.

## Generating BLQ observations¶

The PREDICTIONS section to create **BLQ** data utilises the ~rectnorm() distribution, as follows:-

```
PREDICTIONS: |
p[DV_CENTRAL] = s[CENTRAL]/m[V1]
var = m[ANOISE]**2 + m[PNOISE]**2 * p[DV_CENTRAL]**2
# c[DV_CENTRAL] ~ norm(p[DV_CENTRAL], var)
c[DV_CENTRAL] ~ rectnorm(p[DV_CENTRAL], var, LLQ=0.5)
```

This creates observations with a **LLQ** of 0.5, see Table 34.

Notice that no observations are output below 0.5, as expected. PoPy outputs observations of 0.5, if the generated observation is in the interval [-inf, 0.5].

## Fitting BLQ observations using rectnorm (correct error model)¶

We fit the same (correct) error model, using the same PREDICTIONS section as follows:-

```
PREDICTIONS: |
p[DV_CENTRAL] = s[CENTRAL]/m[V1]
var = m[ANOISE]**2 + m[PNOISE]**2 * p[DV_CENTRAL]**2
# c[DV_CENTRAL] ~ norm(p[DV_CENTRAL], var)
c[DV_CENTRAL] ~ rectnorm(p[DV_CENTRAL], var, LLQ=0.5)
```

*i.e.* a ~rectnorm() distribution, with a **LLQ** of 0.5. Note that, this fitting method does **not** require the LAPLACE objective function, we can use the FOCE objective function instead in PoPy.

See Table 35 for PK curves after fitting.

Note that the fitted curves (solid blue) line are estimated to be below the **LLQ** level of 0.5 at later time points.

The estimated `f[X]`

compared to the true `f[X]`

are shown in Table 36 and Table 37.

Name | Initial | Fitted | True | Prop. Error | Abs. Error |
---|---|---|---|---|---|

f[KA] | 1 | 0.196 | 0.2 | 2.15% | 4.31e-03 |

f[CL] | 1 | 2.02 | 2 | 1.23% | 2.45e-02 |

f[V1] | 20 | 47 | 50 | 5.98% | 2.99e+00 |

Name | Initial | Fitted | True | Prop. Error | Abs. Error |
---|---|---|---|---|---|

f[PNOISE] | 0.1 | 0.139 | 0.15 | 7.38% | 1.11e-02 |

Table 36 and Table 37 show that the `f[KA], f[CL], f[V1], f[PNOISE]`

parameters are recovered well when fitting with ~rectnorm() distribution.

The full set of fitted `f[X]`

variable is shown below:-

```
f[KA] = 0.1957
f[CL] = 2.0245
f[V1] = 47.0079
f[KA_isv,CL_isv,V1_isv] = [
[ 0.1365, 0.0159, 0.0617 ],
[ 0.0159, 0.0390, 0.0200 ],
[ 0.0617, 0.0200, 0.1256 ],
]
f[PNOISE] = 0.1389
f[ANOISE] = 0.0100
```

These fitted values can be compared with fitting alternative error models below.

## Fitting BLQ observations using norm (incorrect error model)¶

Note

See the Depot One Comp PK with BLQ observations set to LLQ script and results used by the PoPy developers for this example.

We fit a (incorrect) error model which treats observations of **LLQ** as actual 0.5 observations, using a ~norm() distribution, as follows:-

```
PREDICTIONS: |
p[DV_CENTRAL] = s[CENTRAL]/m[V1]
var = m[ANOISE]**2 + m[PNOISE]**2 * p[DV_CENTRAL]**2
c[DV_CENTRAL] ~ norm(p[DV_CENTRAL], var)
# c[DV_CENTRAL] ~ rectnorm(p[DV_CENTRAL], var, LLQ=0.5)
```

For fitted curves see Table 38.

Note that the fitted curves (solid blue) line try to stay close to the **BLQ** values at 0.5, which is incorrect, as the PK curve should approach zero concentration instead.

The fitted `f[X]`

values are:-

```
f[KA] = 2.8234
f[CL] = 0.9554
f[V1] = 86.0572
f[KA_isv,CL_isv,V1_isv] = [
[ 1.2020, -0.0141, 0.2416 ],
[ -0.0141, 0.0002, -0.0029 ],
[ 0.2416, -0.0029, 0.0501 ],
]
f[PNOISE] = 0.2289
f[ANOISE] = 0.0100
```

These fitted values are inaccurate compared to the parameters recovered using the ~rectnorm() distribution in section Fitting BLQ observations using rectnorm (correct error model) above.

## Fitting BLQ observations using half LLQ (approx error model)¶

Note

See the Depot One Comp PK with BLQ observations set to 0.5*LLQ script and results used by the PoPy developers for this example.

We fit a simple approx **BLQ** error model, which models observations of **LLQ** as bare 0.5* **LLQ** observations, by preprocessing the original observation data, as follows:-

```
PREPROCESS: |
# use halve value blq data
if c[DV_CENTRAL] <= 0.5 and c[TYPE] == 'obs':
c[DV_CENTRAL] = 0.25
```

The ~norm() distribution is used to model these amended observations (similar to Fitting BLQ observations using norm (incorrect error model) above), see:-

```
PREDICTIONS: |
p[DV_CENTRAL] = s[CENTRAL]/m[V1]
var = m[ANOISE]**2 + m[PNOISE]**2 * p[DV_CENTRAL]**2
c[DV_CENTRAL] ~ norm(p[DV_CENTRAL], var)
# c[DV_CENTRAL] ~ rectnorm(p[DV_CENTRAL], var, LLQ=0.5)
```

For fitted curves using this half **LLQ** approximation, see Table 39.

Note that the fitted curves (solid blue) line get closer to zero (the true asymptotic concentration) as time increases, but are still heavily distorted by assuming the half **LLQ** values are true observations.

The fitted `f[X]`

values are:-

```
f[KA] = 1.9123
f[CL] = 1.6514
f[V1] = 80.2922
f[KA_isv,CL_isv,V1_isv] = [
[ 1.0636, 0.1018, 0.2494 ],
[ 0.1018, 0.0100, 0.0243 ],
[ 0.2494, 0.0243, 0.0596 ],
]
f[PNOISE] = 0.3314
f[ANOISE] = 0.0100
```

These fitted values are similar to the results obtained in Fitting BLQ observations using norm (incorrect error model) and also inaccurate compared to the parameters recovered using the ~rectnorm() distribution in section Fitting BLQ observations using rectnorm (correct error model) above.

## Fit to non-BLQ observations only (reduced data model)¶

Note

See the Depot One Comp PK ignoring BLQ observations. script and results used by the PoPy developers for this example.

We can also just ignore the **BLQ** data, by using PREPROCESS to remove the **LLQ** observations, as follows:-

```
PREPROCESS: |
# ignore blq data
if c[DV_CENTRAL] <= 0.5 and c[TYPE] == 'obs':
return
```

The ~norm() distribution is then used to model the above **LLQ** observations only, see:-

```
PREDICTIONS: |
p[DV_CENTRAL] = s[CENTRAL]/m[V1]
var = m[ANOISE]**2 + m[PNOISE]**2 * p[DV_CENTRAL]**2
c[DV_CENTRAL] ~ norm(p[DV_CENTRAL], var)
# c[DV_CENTRAL] ~ rectnorm(p[DV_CENTRAL], var, LLQ=0.5)
```

The fitted curves are shown in Table 40.

Note that curves are fitted to the above **LLQ** observations only, *i.e.* earlier time points, but there is no data for later **LLQ** time points.

The fitted `f[X]`

values are:-

```
f[KA] = 0.2308
f[CL] = 1.8474
f[V1] = 52.2821
f[KA_isv,CL_isv,V1_isv] = [
[ 0.0000, 0.0002, 0.0004 ],
[ 0.0002, 0.0399, 0.0067 ],
[ 0.0004, 0.0067, 0.0987 ],
]
f[PNOISE] = 0.1491
f[ANOISE] = 0.0100
```

These fitted values are much better then the Fitting BLQ observations using norm (incorrect error model) and Fitting BLQ observations using half LLQ (approx error model) approximatons, but not quite as accurate as the ~rectnorm() distribution results in section Fitting BLQ observations using rectnorm (correct error model).