Skip to content

timecourse

Timecourses, doses and dosing protocols.

The data model of the package:

  • Timecourse is one curve, i.e. values over time with units, an optional uncertainty (sd/se and n for group data), a Dosing protocol and metadata.
  • Dosing is the dosing protocol of a timecourse: the vector of doses given and the times they were given, one route and one unit for all of them; a single administration stays a Dose, Dosing.single wraps one into a protocol of one dose. Timecourse keeps accepting a single dose=Dose(...) keyword, converted into a protocol of one dose; Timecourse.dose reads back the first dose of the protocol.
  • Timecourses is a batch of curves as an xarray.Dataset with a time dimension and any number of sample dimensions (individuals, groups, studies, the dimensions of a simulation scan). Every analysis of the package works on a Timecourses object and returns an xarray.Dataset over the same sample dimensions.
  • DosingRegimen describes repeated dosing for steady state analyses; DosingRegimen.dosing() builds the corresponding Dosing protocol.
from pkpdutils.timecourse import Dose, Route, Timecourse

tc = Timecourse(
    time=[0.5, 1, 2, 4, 8, 12],
    value=[1.2, 2.5, 2.1, 1.3, 0.5, 0.2],
    time_unit="hr",
    unit="mg/l",
    dose=Dose(amount=100, unit="mg", route=Route.ORAL),
    substance="caffeine",
)

Route

Bases: StrEnum

Route of administration.

ORAL stands for every extravascular route (oral, subcutaneous, intramuscular, ...): the substance has an absorption phase and the parameters which need the fraction absorbed are reported relative to it (cl_f, vz_f).

A string is coerced to a member wherever a route is taken, ignoring the case, surrounding blanks and the separator ("ORAL", "iv bolus" and "iv-bolus" are members).

is_iv property

is_iv

Whether the route is intravenous (bolus or infusion).

Dose

Bases: BaseModel

A dose of the substance of a timecourse.

Attributes:

Name Type Description
amount float

amount of the dose (non-negative)

unit str

unit of the amount, an amount (mg, mmol) or an amount per body weight (mg/kg, µmol/kg), see pkpdutils.units.check_dose_unit

route Route

route of administration

time float

time of the dose in the time unit of the timecourse

duration float | None

duration of the infusion in the time unit of the timecourse; required for Route.IV_INFUSION (finite and positive), not allowed otherwise

quantity property

quantity

The dose as a quantity.

per_bodyweight property

per_bodyweight

Whether the dose is an amount per body weight.

DosingRegimen

Bases: BaseModel

Repeated administration of the same dose at a fixed interval.

Attributes:

Name Type Description
dose Dose

the dose given at every administration; its time is the time of the first dose

interval float

dosing interval tau in the time unit of the timecourse

n_doses int | None

number of doses, None for an unspecified number (steady state analyses only need tau)

dose_times

dose_times()

Times of the administrations, dose.time + k * interval.

Raises:

Type Description
ValueError

if n_doses is None.

dosing

dosing()

The protocol of the regimen, Dosing.regimen of dose, interval and n_doses.

Returns:

Type Description
Dosing

The protocol.

Raises:

Type Description
ValueError

if n_doses is None.

Dosing

Bases: BaseModel

The dosing protocol of a timecourse: the doses given and the times they were given.

A protocol has one route and one unit for every dose; Dose stays the single administration and Dosing.single wraps one into a protocol of one dose. The doses are stored sorted by time.

Attributes:

Name Type Description
amounts ndarray

amount of every dose (non-negative), 1-D

times ndarray

time of every dose in the time unit of the timecourse, 1-D, strictly increasing after validation

durations ndarray | None

duration of every infusion in the time unit of the timecourse, None when no dose is an infusion; required with every value finite and positive for Route.IV_INFUSION, not allowed otherwise

unit str

unit of the amounts, see pkpdutils.units.check_dose_unit

route Route

route of administration, shared by every dose of the protocol

n_doses property

n_doses

Number of doses.

doses property

doses

The doses of the protocol as individual Dose objects.

first property

first

The first dose of the protocol.

last property

last

The last dose of the protocol.

intervals property

intervals

Time between consecutive doses, np.diff(times).

tau property

tau

The common dosing interval, None without at least two doses or an irregular protocol.

is_regular property

is_regular

Whether the protocol has a common dosing interval, tau is not None.

total_amount property

total_amount

Sum of the dose amounts.

quantity property

quantity

The total dose amount as a quantity.

per_bodyweight property

per_bodyweight

Whether the doses are an amount per body weight.

single classmethod

single(dose)

Wrap one dose into a protocol of one dose.

Parameters:

Name Type Description Default
dose Dose

the dose.

required

Returns:

Type Description
Dosing

The protocol.

from_doses classmethod

from_doses(doses)

Build a protocol from individual doses.

Parameters:

Name Type Description Default
doses Sequence[Dose]

the doses, at least one, all with the same unit and route.

required

Returns:

Type Description
Dosing

The protocol.

Raises:

Type Description
ValueError

if doses is empty, or the doses have different unit or route.

regimen classmethod

regimen(dose, interval, n_doses)

Build a regular protocol, dose repeated every interval.

Parameters:

Name Type Description Default
dose Dose

the dose given at every administration; its time is the time of the first dose

required
interval float

dosing interval, must be positive

required
n_doses int

number of doses, must be at least 1

required

Returns:

Type Description
Dosing

The protocol with times dose.time + k * interval.

Raises:

Type Description
ValueError

if interval is not positive or n_doses is less than 1.

shifted

shifted(offset)

Copy with every dose time shifted by -offset.

Parameters:

Name Type Description Default
offset float

the offset to subtract from every dose time.

required

Returns:

Type Description
Dosing

The shifted protocol.

Timecourse

Timecourse(*, dose=None, dosing=None, **data)

Bases: BaseModel

One curve of values over time with units, uncertainty, dose and metadata.

Concentration timecourses of a substance and effect timecourses of a pharmacodynamic response use the same class; value is the generic name. A group timecourse (mean of several subjects) carries the standard deviation sd or the standard error se and the number of subjects n; an individual timecourse carries none of them.

Validation converts the arrays to float64, sorts them by time, derives se from sd and n (or sd from se and n) and checks the units.

Attributes:

Name Type Description
time ndarray

sampling times, strictly increasing after validation

value ndarray

values at the sampling times, NaN for missing values

time_unit str

unit of time, e.g. "hr"

unit str

unit of value, e.g. "ng/ml"

sd ndarray | None

standard deviation per time point (group data)

se ndarray | None

standard error per time point (group data)

n float | ndarray | None

number of subjects, one number or one per time point

dosing Dosing | None

the dosing protocol, None without dose information; the constructor also accepts a single dose: Dose keyword, wrapped into a protocol of one dose

substance str

name of the substance or of the effect

label str | None

label of the curve, e.g. the group or the individual

tissue str | None

tissue or matrix the values were measured in, e.g. "plasma"

lloq float | None

lower limit of quantification of the assay behind the values, in their unit; the analysis reads it when NCAOptions.lloq names no limit of its own (pkpdutils.nca), so that a study with two assays or two analytes carries a limit per curve

Construct a timecourse, dose and dosing handled by _dose_to_dosing.

dose is not a field of the model (kept only for backwards compatibility with Dose(...)); declaring it here, rather than relying on the model_validator(mode="before") alone, keeps it a recognized keyword argument for static type checkers.

Parameters:

Name Type Description Default
dose Dose | Dosing | None

a single dose, converted into a protocol of one dose; not allowed together with dosing

None
dosing Dosing | None

the dosing protocol

None
**data Any

the remaining fields of Timecourse.

{}

size property

size

Number of time points.

dose property

dose

First dose of the protocol, None without dosing.

Read-only: model_copy(update={"dose": ...}) is a silent no-op (a property is not a field), use model_copy(update={"dosing": Dosing.single(dose)}) instead.

time_q property

time_q

The times as a quantity.

value_q property

value_q

The values as a quantity.

sd_q property

sd_q

The standard deviations as a quantity, None without sd.

se_q property

se_q

The standard errors as a quantity, None without se.

relative_to_dose

relative_to_dose(which='first')

Copy with the time shifted so that a dose of the protocol is given at time 0.

Returns the timecourse itself when it has no protocol or the chosen dose is already at time 0.

Parameters:

Name Type Description Default
which Literal['first', 'last']

"first" shifts by the time of the first dose, "last" by the time of the last dose.

'first'

Returns:

Type Description
Timecourse

The shifted timecourse, or self when there is nothing to shift.

to_batch

to_batch(dim='individual', label=None)

The curve as a batch of one sample, the counterpart of Timecourses.sel.

Parameters:

Name Type Description Default
dim str

name of the sample dimension of the batch

'individual'
label Any

coordinate label of the single sample, the label of the curve (or 0 when it has none) by default

None

Returns:

Type Description
Timecourses

The batch with one sample.

to_dataframe

to_dataframe()

Convert the curve to a data frame.

Returns:

Type Description
DataFrame

A data frame with the columns time, value and, when present,

DataFrame

sd, se, n.

from_dataframe classmethod

from_dataframe(
    df,
    *,
    time_unit,
    unit,
    time="time",
    value="value",
    sd=None,
    se=None,
    n=None,
    **fields,
)

Create a timecourse from the columns of a data frame.

Parameters:

Name Type Description Default
df DataFrame

the data frame, one row per time point

required
time_unit str

unit of the time column

required
unit str

unit of the value column

required
time str

name of the time column

'time'
value str

name of the value column

'value'
sd str | None

name of the standard deviation column, None for none

None
se str | None

name of the standard error column, None for none

None
n str | None

name of the column with the number of subjects, None for none

None
**fields Any

the remaining fields of Timecourse (dose, substance, label, tissue)

{}

Returns:

Type Description
Timecourse

The timecourse.

Timecourses

Timecourses(ds)

A batch of timecourses as an xarray.Dataset.

The dataset has the dimension time and any number of sample dimensions, e.g. individual, group, study, or the dimensions of a simulation scan. Its variables are

  • value over (*sample_dims, time), the values; NaN marks missing points,
  • sd, se over the same dimensions and n over the sample dimensions (or over (*sample_dims, time) when a count varies over the curve), for group data (optional),
  • dose_amount, dose_time, dose_duration over the sample dimensions and the dose dimension dose_index (optional, the three of them together; dose_duration is a variable of every batch with doses and is NaN where the route is not an infusion, so that every reader of the dose variables works without a case distinction). Every sample carries its protocol in its row, the doses at the front and the trailing columns NaN, so that samples with different numbers of doses share one layout; a single dose batch has one column,
  • the coordinate time with the shared sampling grid, or, when the samples have different sampling times, the variable times over (*sample_dims, time) padded with NaN and an integer coordinate time.

Every variable carries its unit in attrs["units"]; the dataset carries substance, time_unit and unit in its attrs, tissue when the curves name one and route only when doses are present. The properties times and values return the (*sample_shape, n_time) arrays every analysis of the package works on; iteration and sel/isel give single Timecourse objects.

A batch whose samples share one substance and one route carries both in attrs; a batch of several analytes or of several routes carries them as the coordinates substance and route along a sample dimension, which substances and routes read back and the analyses follow per sample (substance and route raise for such a batch). n is one number per sample, or one per sample and time point when a count varies over the curve, as it does for the group curve of a ragged batch (Timecourses.mean); n_subjects is the number of subjects of a sample in either layout.

Several sample dimensions span their cartesian product, which can have combinations without data (no curve was measured for them). Such a sample is all NaN; iteration and sel/isel return a Timecourse with NaN values and dosing=None for it.

Wrap a dataset, see the class documentation for its layout.

Every variable with the time dimension (value, sd, se, times) is transposed to (*sample_dims, time) and every dose variable to (*sample_dims, dose_index), so that the arrays and the data frame of the batch are built from one layout.

Raises:

Type Description
ValueError

if the dataset does not have the layout.

sample_dims property

sample_dims

The dimensions other than time.

sample_shape property

sample_shape

The shape of the sample dimensions.

n_samples property

n_samples

Number of timecourses.

n_time property

n_time

Number of time points (the length of the padded grid for ragged data).

time_unit property

time_unit

Unit of the times.

unit property

unit

Unit of the values.

substances property

substances

The substance of every sample of shape sample_shape, None when they agree.

The coordinate substance along a sample dimension, which a batch of several analytes carries (a parent and its metabolite over (analyte, individual)), as an array of strings. None for a batch whose samples name one substance, which substance returns.

substance property

substance

Name of the substance or effect, the one of the whole batch.

Returns:

Type Description
str

The substance of the batch: the coordinate substance when the

str

batch carries one, attrs["substance"] otherwise.

Raises:

Type Description
ValueError

if the samples name different substances (substances reads them then).

tissue property

tissue

Tissue or matrix the values were measured in, None when it is not known.

routes property

routes

The route of every sample of shape sample_shape, None when they agree.

The coordinate route along a sample dimension, which a batch of several routes carries (the intravenous reference and the oral test of an absolute bioavailability study), as an array of Route members. None for a batch whose samples were given one route, which route returns. The analysis reads the route of every row from here (pkpdutils.nca.nca).

route property

route

Route of the doses, the one of the whole batch, None without dose information.

Returns:

Type Description
Route | None

The route of the batch: the coordinate route when the batch

Route | None

carries one, attrs["route"] otherwise, None without doses.

Raises:

Type Description
ValueError

if the samples were given different routes (routes reads them then).

lloq property

lloq

Limit of quantification per sample of shape sample_shape, None without.

The variable or coordinate lloq over the sample dimensions: the lloq of the curves a batch was built from, or the column the readers of pkpdutils.io carry over (ADNCA ALLOQ). NaN for a sample whose assay names no limit; the analysis reads it when NCAOptions.lloq names no limit of its own.

Raises:

Type Description
ValueError

if lloq carries a dimension which is not a sample dimension, e.g. one limit per time point.

has_uncertainty property

has_uncertainty

Whether sd or se is present.

has_dose property

has_dose

Whether doses are present.

times property

times

Times as an array of shape (*sample_shape, n_time).

values property

values

Values as an array of shape (*sample_shape, n_time).

nominal_times property

nominal_times

The nominal (scheduled) time of every point, None without.

The optional variable nominal_time of shape (*sample_shape, n_time): the time the protocol of the study asked a sample to be taken at, where times are the times it was taken at. The analyses read the actual times; the nominal times are the grid a mean curve over the subjects of a study is taken on (pkpdutils.plot.plot_study_curves), since the actual times of two subjects never coincide. A batch whose variable carries fewer dimensions (one nominal grid for every sample) gets it broadcast to the shape of the values.

sd property

sd

Standard deviations, None without.

se property

se

Standard errors, None without.

n property

n

Counts behind the values, None without.

One number per sample, or one per sample and time point when the batch carries a count per point, as the group curve of mean does; a Timecourse keeps n the same way. n_subjects reduces the second form to one number per sample.

n_subjects property

n_subjects

Number of subjects per sample, None without.

The stored n when it is one number per sample, and the largest count over the time points when it is one per time point: the number of subjects of a group is the number behind its best covered point.

dose_amount property

dose_amount

Dose amounts of shape (*sample_shape, n_dose), None without doses.

dose_time property

dose_time

Dose times of shape (*sample_shape, n_dose), None without doses.

dose_duration property

dose_duration

Infusion durations of shape (*sample_shape, n_dose) (NaN without infusion), None without doses.

dose_unit property

dose_unit

Unit of the doses, None without doses.

n_dose property

n_dose

Size of the dose dimension, the longest protocol of the batch; 0 without doses.

n_doses property

n_doses

Number of doses per sample of shape sample_shape, None without doses.

first_dose_amount property

first_dose_amount

Amount of the first dose per sample, None without doses.

last_dose_amount property

last_dose_amount

Amount of the last dose per sample, None without doses.

first_dose_time property

first_dose_time

Time of the first dose per sample, None without doses.

last_dose_time property

last_dose_time

Time of the last dose per sample, None without doses.

from_arrays classmethod

from_arrays(
    time,
    values,
    *,
    time_unit,
    unit,
    dims=("individual",),
    coords=None,
    sd=None,
    se=None,
    n=None,
    nominal_time=None,
    dose=None,
    route=None,
    substance="substance",
    tissue=None,
)

Create a batch from arrays.

Parameters:

Name Type Description Default
time Any

the sampling grid shared by all samples (1-D), or the times per sample with the shape of values

required
values Any

values of shape (*sample_shape, n_time)

required
time_unit str

unit of the times

required
unit str

unit of the values

required
dims Sequence[str]

names of the sample dimensions, one per leading axis of values

('individual',)
coords Mapping[str, Any] | None

coordinate values per sample dimension (labels of the samples)

None
sd Any | None

standard deviations with the shape of values

None
se Any | None

standard errors with the shape of values

None
n Any | None

the counts, one number, an array of shape sample_shape (one count per sample) or an array of the shape of values (one count per sample and time point)

None
nominal_time Any | None

the nominal (scheduled) time of every point, the sampling grid of the protocol (1-D) or one nominal time per sample and point (the shape of values); the actual time stays what the analyses read

None
dose Dose | Dosing | Mapping[str, Any] | None

one Dose or one Dosing protocol for all samples, or a mapping with amount, unit and optionally time and duration; the arrays of the mapping have the shape sample_shape (one dose per sample) or (*sample_shape, n_dose) (one protocol per sample, padded with NaN, time required); the route is then given by route

None
route Route | str | None

route of the doses when dose is a mapping, a Route or a string it coerces ("oral", "IV_BOLUS")

None
substance str

name of the substance or effect

'substance'
tissue str | None

tissue or matrix the values were measured in, e.g. "plasma"; None when it is not known

None

The dose variables of the batch hold the invariant the analyses rely on: the doses of a sample are the leading columns of its row, sorted by time, and the trailing columns are NaN padding. The constructor enforces it, the rows of a mapping may be given in any order; a dose with an amount but no time (or the other way round) and duplicate dose times within a sample are errors.

Returns:

Type Description
Timecourses

The batch.

Raises:

Type Description
ValueError

if the shapes do not fit, if route is missing for a mapping or contradicts the route of a Dose or Dosing, if a mapping breaks the invariant above, or if a sample dimension is named dose_index.

from_timecourses classmethod

from_timecourses(
    timecourses, dim="individual", labels=None
)

Create a batch from single timecourses along one sample dimension.

The timecourses must share time_unit, unit and tissue. If all sampling grids are equal the grid becomes the time coordinate, otherwise the times are stored per sample and shorter curves are padded with NaN.

Curves of different substances (a parent and its metabolite) and curves given by different routes (the intravenous reference and the oral test of a bioavailability study) go into one batch: the differing values become the coordinates substance and route along dim, which Timecourses.substances and Timecourses.routes read back and the analysis follows per sample. A batch whose curves agree carries the one value in attrs as before and grows no coordinate.

Either all or no curves carry a dosing protocol, and all protocols need the same dose unit. The protocols are padded to the longest one. The batch keeps one n per sample, and the counts per time point when the n of a curve varies over its time points (n_subjects reads the number of subjects back either way). sd, se and n are kept only when every curve carries them; a field which some curves are missing is dropped for the whole batch and logs a warning.

Parameters:

Name Type Description Default
timecourses Sequence[Timecourse]

the curves

required
dim str

name of the sample dimension

'individual'
labels Sequence[Any] | None

coordinate labels of the samples, the label of every timecourse (or its index when missing) by default

None

Returns:

Type Description
Timecourses

The batch.

Raises:

Type Description
ValueError

for an empty sequence, differing units or tissues, doses on some but not all curves, or doses with different units.

from_dataframe classmethod

from_dataframe(
    df,
    *,
    sample,
    time_unit,
    unit,
    time="time",
    value="value",
    sd=None,
    se=None,
    n=None,
    nominal_time=None,
    lloq=None,
    dose_amount=None,
    dose_unit=None,
    dose_time=None,
    route=None,
    substance="substance",
    tissue=None,
)

Create a batch from a long data frame, one row per sample and time point.

Several sample columns span their cartesian product; a combination without rows in df becomes a sample with NaN values, which iteration and sel/isel return as a Timecourse with NaN values and dose=None.

Parameters:

Name Type Description Default
df DataFrame

the data frame

required
sample Sequence[str]

the columns which identify a sample; they become the sample dimensions, several columns give their cartesian product with NaN for missing combinations

required
time_unit str

unit of the time column

required
unit str

unit of the value column

required
time str

name of the time column

'time'
value str

name of the value column

'value'
sd str | None

name of the standard deviation column

None
se str | None

name of the standard error column

None
n str | None

name of the column with the number of subjects; the batch keeps one number per sample, and the counts per time point when the column varies within a sample

None
nominal_time str | None

name of the column with the nominal (scheduled) time of the point, in time_unit; it becomes the variable nominal_time of the batch and the actual time column stays what the analyses read

None
lloq str | None

name of the column with the limit of quantification, which has to be constant within a sample; it becomes the coordinate lloq along the sample dimension

None
dose_amount str | None

name of the dose column (constant per sample without dose_time, one value per dose time with it)

None
dose_unit str | None

unit of the doses, required with dose_amount

None
dose_time str | None

name of the dose time column, 0 by default; every distinct (dose_time, dose_amount) pair of a sample is one dose of its protocol, rows with NaN dose columns are observations only

None
route Route | str | None

route of the doses, required with dose_amount, a Route or a string it coerces ("oral", "IV_BOLUS")

None
substance str

name of the substance or effect

'substance'
tissue str | None

tissue or matrix the values were measured in, e.g. "plasma"

None

The batch is built from the padded arrays of the frame, not from one Timecourse per sample: the checks of a single curve (at least two time points, no NaN and no duplicate times) and of a single protocol (finite, non-negative amounts, one amount per dose time) are made for every sample at once and name the sample they fail for.

Returns:

Type Description
Timecourses

The batch.

Raises:

Type Description
ValueError

if sample is empty, if the frame holds no sample, if a column holds a value which is neither missing nor a number, if a sample has fewer than two time points, a NaN time or duplicate times, if the limit of quantification is not constant within a sample, or if the doses of a sample are not a valid protocol; every one of them names the sample.

from_dataset classmethod

from_dataset(
    ds,
    value,
    *,
    unit,
    time_unit,
    time_dim="_time",
    time=None,
    dose=None,
    route=None,
    substance=None,
    tissue=None,
)

Create a batch from a dataset of a simulation, e.g. a parameter scan.

Parameters:

Name Type Description Default
ds Dataset

dataset with the time dimension time_dim and the variable value over it and the scan dimensions

required
value str

name of the variable with the values

required
unit str

unit of the values

required
time_unit str

unit of the times

required
time_dim str

name of the time dimension

'_time'
time str | None

name of the variable with the time values, the coordinate of time_dim by default

None
dose Dose | Dosing | Mapping[str, Any] | None

the doses, as in from_arrays: one Dose or one Dosing protocol for all samples, or a mapping of arrays whose rows are sorted by dose time with the NaN padding trailing

None
route Route | str | None

route of the doses when dose is a mapping, a Route or a string it coerces ("oral", "IV_BOLUS")

None
substance str | None

name of the substance, value by default

None
tissue str | None

tissue or matrix the values were measured in, e.g. "plasma"

None

Returns:

Type Description
Timecourses

The batch with the scan dimensions as sample dimensions.

Raises:

Type Description
ValueError

if value has no dimension time_dim, if the time values are not one dimensional, or if dose does not fit the batch (from_arrays).

from_xresult classmethod

from_xresult(xres, selection, *, dose=None, substance=None)

Create a batch from the result of an sbmlsim simulation.

sbmlsim is not a dependency; an XResult is used by its attributes: xres.xds is the dataset with the _time dimension and xres.uinfo maps selection and "time" to unit strings.

Parameters:

Name Type Description Default
xres Any

the sbmlsim.result.XResult

required
selection str

the variable of the result, e.g. "[Cve_mid]"

required
dose Dose | Dosing | None

one dose or one dosing protocol for all samples

None
substance str | None

name of the substance, selection by default

None

Returns:

Type Description
Timecourses

The batch with the scan dimensions as sample dimensions.

relative_to_dose

relative_to_dose(which='first')

Copy with the times of every sample relative to a dose of its own protocol.

Every sample is shifted by the time of its first (or last) dose, so that this dose is at time 0; the dose times of its protocol are shifted with it and a sample without a protocol stays where it is. The batch is returned unchanged when it carries no doses or when every dose time is already 0.

Equal shifts keep the layout of the batch, a shared sampling grid included. Shifts which differ from sample to sample move the samples against each other: the times of every sample are then placed on the union of the shifted grids, with NaN values where a sample has no point at a time of another sample.

Parameters:

Name Type Description Default
which Literal['first', 'last']

"first" shifts every sample by the time of its first dose, "last" by the time of its last dose.

'first'

Returns:

Type Description
Timecourses

The shifted batch, or self when there is nothing to shift.

select

select(**indexers)

A sub-batch by label, list or slice on the sample dimensions and their coordinates.

The counterpart of sel, which returns a single Timecourse and needs a label for every sample dimension: select keeps the dimensions and returns a batch, so that the arm of a study, a dose group or the subjects of a period can be analysed on their own. A single label therefore does not drop its dimension, it keeps it with one sample.

The name of an indexer is a sample dimension or a coordinate along one (treatment, sex, the dose group of the individuals, as the readers of pkpdutils.io build them); its value is a label, a list of labels or a slice of labels, whose bounds are both included, as in xarray.Dataset.sel. The selected samples keep the order of the batch. A sample dimension without labels is selected by integer position instead, where a slice is the usual python slice with an exclusive stop.

A list names the samples the caller expects, so every label of it has to be in the batch: a list holding a label which no sample carries raises and names it, rather than quietly returning the samples of the other labels. A slice is a range and is not checked that way.

Parameters:

Name Type Description Default
**indexers Any

label, list of labels or slice per sample dimension or coordinate along one.

{}

Returns:

Type Description
Timecourses

The sub-batch.

Raises:

Type Description
ValueError

if a name is neither a sample dimension nor a coordinate along one, if a label of a list is not in the batch, or if no sample of the batch matches.

groupby

groupby(coord)

Iterate over the groups of a coordinate as sub-batches.

The groups come in the order of their first appearance along the dimension of the coordinate, so that a study keeps the order of its table; every group is a Timecourses with the same layout as the batch.

Parameters:

Name Type Description Default
coord str

a sample dimension or a coordinate along one, e.g. the dose group or the treatment of the individuals.

required

Yields:

Type Description
Any

The value of the coordinate and the sub-batch of the samples

Timecourses

carrying it.

Raises:

Type Description
ValueError

if coord is neither a sample dimension nor a coordinate along one.

mean

mean(dim, *, spread='sd', min_n=1)

The mean curve over one sample dimension, with its spread and count.

The group curve a publication reports: at every time point the arithmetic mean \(\bar c_j\) of the samples with a finite value there, their standard deviation \(s_j\) (\(n_j - 1\) degrees of freedom) and the standard error \(s_j / \sqrt{n_j}\); a point covered by fewer than min_n samples is NaN.

n is the count \(n_j\) of its own time point, not one number for the curve, so that \(\mathrm{se}_j = s_j/\sqrt{n_j}\) holds at every point of a ragged group as well, where the late points carry fewer subjects than the early ones. Timecourses.n_subjects is the number of subjects of the group, the largest of the counts.

The group curve carries sd and se: the standard deviation is the scatter of the samples at the point and the standard error follows from it through the count of the point. spread names the statistic which is computed from the curves and is kept for the symmetry with plot_mean_timecourse; since n is the count of the point itself, the two statistics imply each other and the result is the same either way.

The samples need a shared sampling grid; a ragged batch is placed on the union of the grids of its samples first, with NaN where a sample has no point at the time of another. An existing sd, se or n of the samples is not propagated: the spread of the group curve is the scatter of the curves which were reduced.

The dosing protocol of the group is the protocol of its samples when they share one, and the protocol of the first sample with a warning when they do not; relative_to_dose aligns the samples beforehand when they were dosed at different times.

Parameters:

Name Type Description Default
dim str

the sample dimension to reduce.

required
spread Literal['sd', 'se']

the statistic which is computed from the curves, the other one is derived from it through n; both give the same pair.

'sd'
min_n int

fewest samples a time point must be covered by.

1

Returns:

Type Description
Timecourses

The batch of group curves over the remaining sample dimensions.

Raises:

Type Description
ValueError

if dim is not a sample dimension or min_n is not positive.

dose_normalized

dose_normalized(reference=None)

The values divided by the dose, for the overlay of several dose levels.

Dose normalization removes the dose from the curves of a dose escalation: with linear kinetics the normalized curves \(c(t) / D\) of every dose level fall on top of each other, and a deviation from that overlay is the figure of a dose dependency. Every sample is divided by the amount of its first dose, or by reference when one is given, and sd and se are divided with it; the unit of the values becomes unit / dose_unit, simplified by pint ("nanogram / milliliter" per "milligram" gives "nanogram / milligram / milliliter"). The doses themselves are kept, so that a figure still draws them, and a sample without a dose amount becomes NaN.

Parameters:

Name Type Description Default
reference float | Quantity | None

the amount every sample is divided by, as a number in the dose unit of the batch or as a pint quantity converted to it; None divides every sample by its own first dose.

None

Returns:

Type Description
Timecourses

The normalized batch.

Raises:

Type Description
ValueError

without doses, if reference is not positive or carries a unit which is not a dose unit of the batch.

dosing_of

dosing_of(**indexers)

The dosing protocol of one sample, selected by coordinate label.

Parameters:

Name Type Description Default
**indexers Any

one label per sample dimension, as for sel.

{}

Returns:

Type Description
Dosing | None

The protocol, None without doses or for a sample combination

Dosing | None

which is not in the batch.

Raises:

Type Description
ValueError

without a label for every sample dimension.

isel

isel(**indexers)

One timecourse by integer position on every sample dimension.

sel

sel(**indexers)

One timecourse by coordinate label on every sample dimension.

to_dataframe

to_dataframe()

The batch as a long data frame: the sample coordinates, time, value and the optional columns.

One row per sample and time point. The limit of quantification of a sample, which is one number per sample, is repeated in every row of it (from_dataframe(lloq="lloq") reads it back). The dose variables are not part of the frame: they live over the dose dimension, not over the time dimension, and there is no one dose per row; to_events writes the dosing protocol as its own rows.

Returns:

Type Description
DataFrame

The long data frame.

from_events classmethod

from_events(df, **kwargs)

Read a batch from event records, pkpdutils.io.read_events.

Parameters:

Name Type Description Default
df DataFrame

the event table, one row per dose or observation

required
**kwargs Any

the arguments of pkpdutils.io.read_events

{}

Returns:

Type Description
Timecourses

The batch.

to_events

to_events(**kwargs)

Write the batch as event records, pkpdutils.io.write_events.

Parameters:

Name Type Description Default
**kwargs Any

the arguments of pkpdutils.io.write_events

{}

Returns:

Type Description
DataFrame

The event table.

from_pknca classmethod

from_pknca(conc, dose, **kwargs)

Read a batch from the two tables of PKNCA, pkpdutils.io.read_pknca.

Parameters:

Name Type Description Default
conc DataFrame

the concentration table

required
dose DataFrame

the dose table

required
**kwargs Any

the arguments of pkpdutils.io.read_pknca

{}

Returns:

Type Description
Timecourses

The batch.

to_pknca

to_pknca(*args, **kwargs)

Write the batch as the two tables of PKNCA, pkpdutils.io.write_pknca.

Parameters:

Name Type Description Default
*args Any

the paths of pkpdutils.io.write_pknca

()
**kwargs Any

its keyword arguments

{}

Returns:

Type Description
tuple[DataFrame, DataFrame]

The concentration table and the dose table.

from_adnca classmethod

from_adnca(df, **kwargs)

Read a batch from a CDISC ADaM ADNCA dataset, pkpdutils.io.read_adnca.

Parameters:

Name Type Description Default
df DataFrame

the ADNCA dataset

required
**kwargs Any

the arguments of pkpdutils.io.read_adnca

{}

Returns:

Type Description
Timecourses

The batch.

to_adnca

to_adnca(*args, **kwargs)

Write the batch as a CDISC ADaM ADNCA dataset, pkpdutils.io.write_adnca.

Parameters:

Name Type Description Default
*args Any

the path of pkpdutils.io.write_adnca

()
**kwargs Any

its keyword arguments

{}

Returns:

Type Description
DataFrame

The dataset.

pad_rows

pad_rows(arrays, n_columns)

Stack 1-D arrays of different lengths into (len(arrays), n_columns), padded with NaN.

The padding layout of a batch: the values of a sample are the leading columns of its row, the trailing columns are NaN.

Parameters:

Name Type Description Default
arrays Sequence[ndarray]

one array per sample, none longer than n_columns.

required
n_columns int

number of columns, at least the length of the longest array.

required

Returns:

Type Description
ndarray

The padded array.

pad_protocols

pad_protocols(protocols, n_dose)

Stack dosing protocols into (len(protocols), n_dose) arrays padded with NaN.

Parameters:

Name Type Description Default
protocols Sequence[Dosing | None]

one protocol per sample, None for a sample without doses.

required
n_dose int

number of columns, at least the longest protocol.

required

Returns:

Type Description
ndarray

The amounts, the times and the durations; the doses of a sample are at

ndarray

the front of its row, the remaining columns are NaN.

dose_mapping

dose_mapping(protocols, *, allow_mixed_routes=False)

The dose mapping and the route of a batch built from per sample protocols.

The protocols of a batch share one dose unit; they are padded to the longest one (pad_protocols), a sample without a protocol gets a row of NaN. The mapping always carries a duration entry, NaN where the route is not an infusion: dose_duration is a variable of every batch with doses, so that the readers of the dose variables need no case distinction.

The protocols share one route unless allow_mixed_routes says otherwise; the route of the first protocol is returned then and the caller carries the route of every sample as the coordinate route along a sample dimension (Timecourses.routes).

Parameters:

Name Type Description Default
protocols Sequence[Dosing | None]

one protocol per sample, None for a sample without doses.

required

Other Parameters:

Name Type Description
allow_mixed_routes bool

whether the protocols may have been given by different routes.

Returns:

Type Description
dict[str, Any] | None

The mapping for Timecourses.from_arrays and the route, both None

Route | None

when no sample carries a protocol.

Raises:

Type Description
ValueError

if the protocols do not share one dose unit, or one route without allow_mixed_routes.