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 39.
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 40 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 41 and Table 42.
Name | Initial | Fitted | True | Abs. Error | Prop. Error |
---|---|---|---|---|---|
f[KA] | 1 | 0.195 | 0.2 | 4.50e-03 | 2.25% |
f[CL] | 1 | 2.02 | 2 | 2.48e-02 | 1.24% |
f[V1] | 20 | 47 | 50 | 3.03e+00 | 6.06% |
Name | Initial | Fitted | True | Abs. Error | Prop. Error |
---|---|---|---|---|---|
f[PNOISE] | 0.1 | 0.139 | 0.15 | 1.11e-02 | 7.41% |
Table 41 and Table 42 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.1955
f[CL] = 2.0248
f[V1] = 46.9689
f[KA_isv,CL_isv,V1_isv] = [
[ 0.1374, 0.0156, 0.0621 ],
[ 0.0156, 0.0392, 0.0199 ],
[ 0.0621, 0.0199, 0.1255 ],
]
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 43.
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.7156
f[CL] = 0.9561
f[V1] = 86.1193
f[KA_isv,CL_isv,V1_isv] = [
[ 1.1675, -0.0135, 0.2387 ],
[ -0.0135, 0.0002, -0.0028 ],
[ 0.2387, -0.0028, 0.0507 ],
]
f[PNOISE] = 0.2288
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 44.
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.2625
f[CL] = 1.6570
f[V1] = 80.1152
f[KA_isv,CL_isv,V1_isv] = [
[ 0.7148, 0.0848, 0.2052 ],
[ 0.0848, 0.0101, 0.0244 ],
[ 0.2052, 0.0244, 0.0591 ],
]
f[PNOISE] = 0.3301
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 45.
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.2317
f[CL] = 1.8509
f[V1] = 52.4457
f[KA_isv,CL_isv,V1_isv] = [
[ 0.0000, 0.0002, 0.0004 ],
[ 0.0002, 0.0393, 0.0064 ],
[ 0.0004, 0.0064, 0.0990 ],
]
f[PNOISE] = 0.1498
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).