Skip to content

nca.options

Options and flags of the non-compartmental analysis.

NCAOptions selects the methods of an analysis: the kind of timecourse, the trapezoid rule, the terminal phase selection, the handling of values below the limit of quantification (BLQRules, one rule per position of the curve) and the dosing intervals of a multiple dose analysis. NCAFlag names the conditions an analysis reports per sample instead of raising or warning.

Kind

Bases: StrEnum

What a timecourse measures.

AUCMethod

Bases: StrEnum

Trapezoid rule of the areas, see docs/nca.md.

TerminalMethod

Bases: StrEnum

Selection of the points of the terminal log-linear regression.

BLQHandling

Bases: StrEnum

Handling of values below the lower limit of quantification.

BLQAction

Bases: StrEnum

What happens to a value below the lower limit of quantification.

The action of a position of the curve (BLQRules); a float in place of a member imputes that number. DROP and KEEP leave no imputed value behind, every other action writes one, which enters the areas and, unless BLQRules.terminal_regression, stays out of the terminal regression.

C0Method

Bases: StrEnum

Estimate of the concentration at time 0 after an intravenous bolus.

UncertaintyMethod

Bases: StrEnum

How the uncertainty of group timecourses is propagated to the parameters.

BootstrapSpread

Bases: StrEnum

Which spread the bootstrap resamples every time point with.

BootstrapDistribution

Bases: StrEnum

Distribution the bootstrap draws every time point from.

NCAFlag

Bases: IntFlag

Conditions reported per sample in the flags variable of a result.

BLQRules

Bases: BaseModel

Rules for the values below the lower limit of quantification, by position.

The tools slice a profile on two incompatible axes and a rule set is expressed on one of them, never on both (the model raises for a mixture):

  • the positional axis first, middle, last: the values before the first measurable value, between two measurable values and after the last measurable value (PKNCA conc.blq with "first"/"middle"/"last", Pumas Dict(:first => :keep, :middle => :drop, :last => :keep));
  • the tmax axis before_tmax, after_tmax, split at the maximum of the measurable values (PKNCA "before.tmax"/"after.tmax", PKanalix, which imputes 0 before and LLOQ/2 after the maximum).

A rule is a BLQAction or a number, which is imputed as it is; a position without a rule drops its values. A row whose values are all below the limit has no measurable value: every value of it counts as first on the positional axis and as after_tmax on the tmax axis.

An imputed value enters the areas (auc_all reports what the imputation added to the tail) and stays out of the terminal regression unless terminal_regression is set; a value which BLQAction.KEEP keeps is treated the same way, since a value below the limit of quantification is not a quantified value. ICH M13A (2024) asks for exactly that: values below the limit are "treated as zero in PK parameter calculations" and "omitted from the calculation of kel and t½" (BLQRules.ich_m13a).

Attributes:

Name Type Description
first BLQAction | float | None

rule for the values before the first measurable value

middle BLQAction | float | None

rule for the values between two measurable values

last BLQAction | float | None

rule for the values after the last measurable value

before_tmax BLQAction | float | None

rule for the values before the maximum

after_tmax BLQAction | float | None

rule for the values at or after the maximum

terminal_regression bool

whether an imputed or kept value below the limit may enter the terminal regression

by_tmax property

by_tmax

Whether the rules split the curve at the maximum instead of by position.

from_handling classmethod

from_handling(handling)

The rules of one of the two classic BLQHandling values.

Parameters:

Name Type Description Default
handling BLQHandling

BLQHandling.NAN or BLQHandling.ZERO_BEFORE_TMAX.

required

Returns:

Type Description
BLQRules

first=middle=last=DROP for NAN and before_tmax=ZERO,

BLQRules

after_tmax=DROP for ZERO_BEFORE_TMAX.

ich_m13a classmethod

ich_m13a()

The rule set of ICH M13A (2024): zero at both ends, dropped in between.

Returns:

Type Description
BLQRules

first=ZERO, middle=DROP, last=ZERO, the imputed values out of

BLQRules

the terminal regression.

pkanalix classmethod

pkanalix()

The default rule set of PKanalix: 0 before the maximum, LLOQ/2 after it.

Returns:

Type Description
BLQRules

before_tmax=ZERO, after_tmax=HALF_LLOQ.

pumas classmethod

pumas()

The default rule set of Pumas: the ends kept, the middle dropped.

Returns:

Type Description
BLQRules

first=KEEP, middle=DROP, last=KEEP.

Acceptance

Bases: BaseModel

Thresholds a sample has to meet for its terminal phase to be accepted.

A regulatory analysis does not report every terminal regression it can compute: the adjusted \(R^2\) of the regression, the extrapolated share of \(\mathrm{AUC}_{0\text{-}\infty}\), the number of half-lives the window covers and the number of points of the regression are checked against thresholds, and the samples which fail them are reported separately or left out of the summary statistics. PKanalix ships the four thresholds of Acceptance.pkanalix as its defaults and restricts its summary statistics to the individuals which meet them; Phoenix WinNonlin has the same three continuous criteria with an Accepted/Not_Accepted flag and ships no thresholds; PKNCA spells them as the exclusion rules exclude_nca_min.hl.adj.r.squared(), exclude_nca_max.aucinf.pext(), exclude_nca_span_ratio() and exclude_nca_count_conc_measured().

Every threshold is None by default, so the default analysis accepts every sample, and a threshold which is set is checked only where the sample carries the value (a sample without a terminal phase has no adjusted \(R^2\), so it fails the criterion).

Attributes:

Name Type Description
r2_adj_min float | None

smallest adjusted \(R^2\) of the terminal regression (lambda_z_r2_adj)

extrapolation_max float | None

largest extrapolated fraction \((\mathrm{AUC}_{0\text{-}\infty,\mathrm{pred}} - \mathrm{AUC}_{0\text{-}t_\mathrm{last}}) / \mathrm{AUC}_{0\text{-}\infty,\mathrm{pred}}\), the predicted variant PKanalix and Phoenix check

span_min float | None

smallest number of half-lives the terminal window covers (lambda_z_span)

n_points_min int | None

smallest number of points of the terminal regression (lambda_z_n_points)

exclude bool

whether a sample which is not accepted is also marked excluded, which keeps it out of the summary statistics and of the statistics of pkpdutils.stats

any_threshold property

any_threshold

Whether a threshold is set at all.

pkanalix classmethod

pkanalix(*, exclude=False)

The default thresholds of PKanalix.

Adjusted \(R^2\) of at least 0.98, at most 20 % extrapolated area, a span of at least 3 half-lives and at least 3 points of the regression.

Parameters:

Name Type Description Default
exclude bool

whether a sample which fails a threshold is also excluded.

False

Returns:

Type Description
Acceptance

The thresholds.

TerminalPhase

Bases: BaseModel

Selection of the points of the terminal log-linear regression.

After an intravenous infusion the samples taken at or before the end of the infusion (t <= t_dose + dose_duration) are no candidates of any window, whatever method says: the concentration still rises while the drug is given, so the first point a window may start at is the first sample strictly after the infusion (Phoenix WinNonlin). It is the only rule of the selection which the route decides.

Attributes:

Name Type Description
method TerminalMethod

the selection rule

min_points int

minimal number of points of a regression (at least 3)

exclude_cmax bool

whether the windows must start after the point of the maximum (True) or may start anywhere (False). It applies to BEST_FIT and to LAST_N, whose window then holds the points after the maximum when n_points reaches beyond it (fewer points than asked for, NCAFlag.TOO_FEW_POINTS below min_points); it does not apply to MANUAL, which regresses the given points as they are, and ALL_AFTER_TMAX starts after the maximum anyway

n_points int | None

number of points for LAST_N

points tuple[int, ...] | None

indices of the points (in the time order of the curve) for MANUAL

min_adj_r2 float | None

minimal adjusted R² a regression must reach, None for no limit

tie_tolerance float

a window with more points wins over the best adjusted R² when its adjusted R² is within this tolerance of the best

windows dict[Any, tuple[float, float]] | None

the terminal window (t_first, t_last) of single samples, keyed by the sample label (the label of a batch with one sample dimension, the tuple of labels of a batch with several, and the string "*" for every sample which the mapping does not name). A sample with a window regresses the points inside it, in the times of the analysis (relative to its reference dose), as TerminalMethod.MANUAL does with indices; every other sample follows method. This is the per-profile window of the interactive tools (Phoenix Lambda_z_lower/Lambda_z_upper, the "Check lambda_z" tab of PKanalix), and pkpdutils.nca.NCAResult.terminal_windows writes the windows of a result back in this form, so that a reviewed analysis is re-run unchanged

keep_candidates bool

whether the regression keeps the table of every candidate window instead of the chosen one alone (pkpdutils.nca.terminal.TerminalFit.candidates). The analysis of a single curve (pkpdutils.nca.nca_single, or a batch of one sample) then reports the windows as the point variables candidate_t_first, candidate_n_points and candidate_r2_adj over the dimension candidate, which pkpdutils.plot.plot_terminal_windows draws: the diagnostic of the judgement call behind the half-life, as the Slopes Selector of Phoenix WinNonlin and the "Check lambda_z" tab of PKanalix show it. A batch of several samples keeps no table, since the windows of a row are a table of their own and the rows need not have equally many of them

NCAOptions

Bases: BaseModel

Options of a non-compartmental analysis.

Attributes:

Name Type Description
kind Kind

concentration or effect timecourses

auc_method AUCMethod

trapezoid rule of the areas

terminal TerminalPhase

selection of the terminal phase

lloq float | None

lower limit of quantification in the unit of the values, None to take the per-sample lloq of the batch (the coordinate the readers of pkpdutils.io write), and no limit without one

blq BLQHandling | BLQRules

handling of values below lloq, one of the two classic BLQHandling values or a BLQRules rule set by position

c0_method C0Method

estimate of C(0) after an intravenous bolus

extrapolation_warning float

fraction of AUC(0-inf) above which EXTRAPOLATION_HIGH is set

acceptance Acceptance

thresholds of the terminal phase every sample is checked against (Acceptance); the result carries accepted and, where Acceptance.exclude is set, excluded

partial_aucs dict[str, tuple[float, float]]

named partial areas, name to (t_start, t_end) in the time unit of the batch, relative to the first dose of the protocol. Every one of them becomes a variable of the result with the unit of auc_last; an interval which reaches beyond the last measurable value is completed with the terminal regression and the sample is flagged NCAFlag.PARTIAL_EXTRAPOLATED. AUC(0-72) of a drug with a long half-life is {"auc_0_72": (0.0, 72.0)} (ICH M13A 2024)

tau float | None

length of the last dosing interval, None to take it from the dosing protocol (the distance of the last two doses); it is needed for a steady state curve given with its last dose only and it overrides the protocol for the last interval

tau_tolerance float

how far the last sample of the analysed dosing interval may fall short of its end, as a fraction of tau, before the interval is given up as incomplete. Within the tolerance the exposure of the interval is completed with the terminal regression, auc_tau_extrap_fraction reports the share which was extrapolated and the sample is not flagged; beyond it every steady state parameter is NaN and the sample carries NCAFlag.INCOMPLETE_INTERVAL. The default 0.1 covers the sample which was taken a few minutes before or after the nominal end of the interval, the case EMA and Phoenix WinNonlin both describe; 0 switches the completion off

intervals bool

whether the per-interval parameters (interval_*) are part of the result of a multiple dose analysis

units dict[str, str]

reporting units of the result, variable name to unit ({"auc_inf_obs": "h*ng/mL", "cl_f": "mL/min"}). The analysis runs in the units of the batch as before and the result is converted at the end (pkpdutils.result.ParameterResult.to_units), together with the uncertainty, summary and dose normalized variables of every named parameter; an empty mapping leaves the derived units as they are

effect_threshold float | None

threshold of time_above for effect timecourses, None for none

n_workers int | None

workers of the analysis. None is automatic: the calling thread up to pkpdutils.parallel.NCA_WORKER_THRESHOLD rows and one worker per usable core, at most 8, above it; 1 is always serial and n > 1 uses that many workers. The core is vectorized numpy and releases the GIL, so its workers are threads of the calling process (pkpdutils.parallel) and no if __name__ == "__main__": guard is needed; the fit (FitOptions.n_workers) uses processes and does need one

chunk_rows int

most rows of a chunk of the vectorized core, which bounds its memory: a run holds the temporaries of as many chunks as run at once, min(n_workers, n_chunks) * chunk_rows rows. The chunks are mapped in order; how many there are follows from the rows, the workers and this bound (pkpdutils.parallel.split_rows), so a serial run of a small batch is one chunk whatever n_workers says

uncertainty UncertaintyMethod | None

propagation of sd/se to the parameters; None selects BOOTSTRAP when the batch carries an uncertainty and NONE otherwise

n_boot int

number of bootstrap replicates

seed int | None

seed of the bootstrap random generator; the default None draws from a fresh generator, so a bootstrap is not reproducible

ci_level float

level of the confidence intervals

bootstrap_spread BootstrapSpread

whether the replicates are drawn with se or sd

bootstrap_distribution BootstrapDistribution

normal or log-normal draws

delta_step float

relative perturbation of a point, in units of its se, for the delta method

blq_rules property

blq_rules

The rule set of blq, the two classic BLQHandling values included.

Returns:

Type Description
BLQRules

blq itself when it is a BLQRules, else the rules of

BLQRules

BLQRules.from_handling.

resolve_uncertainty

resolve_uncertainty(has_uncertainty)

The uncertainty method of an analysis.

Parameters:

Name Type Description Default
has_uncertainty bool

whether the batch carries sd or se

required

Returns:

Type Description
UncertaintyMethod

uncertainty when set, else BOOTSTRAP for a batch with an

UncertaintyMethod

uncertainty and NONE without.

decode_flags

decode_flags(value)

Names of the flags set in an integer flag value, in bit order.

Parameters:

Name Type Description Default
value int

an integer combination of NCAFlag values.

required

Returns:

Type Description
list[str]

The names of the set flags, in the declaration order of NCAFlag.