Low-Level API
run_ivivc chains five public functions. Calling them directly gives control over each stage — to inspect or replace the unit impulse responses, to fit the correlation on absorption profiles that did not come from deconvolve, or to predict from dissolution curves built elsewhere. This page runs on the same Simulated Data as the Getting started example.
Step 1: Convert the PK table to profiles
profiles_from_dataframe turns the long-format PK table into one TimeValueProfile per (subject, formulation) pair. Dissolution needs no conversion: every function below takes it as you hold it — the long-format DataFrame (formulation, time, diss columns), a Dict(formulation => (times, values_or_callable)) of your own curves (Supplying Dissolution Curves), or a DissolutionFit (Parametric Dissolution Models).
pk_profiles = profiles_from_dataframe(
pk_df;
id_col = :id,
formulation_col = :formulation,
time_col = :time,
value_col = :conc,
)
length(pk_profiles)76Step 2: Fit unit impulse responses
fit_uir fits a PolyExponential to each subject's reference profile, selecting the number of exponential terms by AICc unless n_exp is given. Every stage accepts a skipped sink that collects one (; id, stage, reason) record per exclusion. Subject 1 has no IV profile and is skipped here.
skipped = NamedTuple[]
uir_profiles = fit_uir(pk_profiles; fast_formulation = "IV", skipped)
uir_profiles[1](id = 3, formulation = "IV", uir = InVitroInVivoCorrelation.PolyExponential{Float64, Float64}([8.71923407458454], [0.2098435391797445], 1.0, 1.0))Step 3: Deconvolve to absorption profiles
deconvolve recovers the fraction absorbed over time for every (subject, formulation) pair by numerical deconvolution against that subject's UIR. It returns the individual profiles together with the mean absorption curve per formulation — an object you hand to the correlation fit and the plots, or write out with DataFrame(abs_source). The three oral profiles of subject 1 have no UIR to deconvolve against and join the sink:
abs_profiles, abs_source = deconvolve(pk_profiles, uir_profiles; fast_formulation = "IV", skipped)
DataFrame(skipped)| Row | id | stage | reason |
|---|---|---|---|
| Int64 | Symbol | String | |
| 1 | 1 | uir_fit | no profile for fast_formulation=IV |
| 2 | 1 | deconvolution | no fitted UIR available (formulation=FormA) |
| 3 | 1 | deconvolution | no fitted UIR available (formulation=FormB) |
| 4 | 1 | deconvolution | no fitted UIR available (formulation=FormC) |
Step 4: Fit the IVIVC model
fit_ivivc fits a correlation model between the dissolution curves and the mean absorption curves. The built-in AffineTimeLinearModel predicts absorption in three steps:
- Time map — convert in vivo time to in vitro time: $t_\text{vitro} = \text{time\_scale} \cdot t_\text{vivo} + \text{time\_shift}$
- Dissolution look-up — evaluate the dissolution curve at that in vitro time
- Fraction map — convert fraction dissolved to fraction absorbed: $F_\text{abs} = \text{abs\_scale} \cdot F_\text{diss} + \text{abs\_intercept}$
validation_formulation keeps one formulation out of the fit so that it can be predicted afterwards.
model = fit_ivivc(
diss_df,
abs_source,
AffineTimeLinearModel();
validation_formulation = "FormB",
)InVitroInVivoCorrelation.IVIVCModel{InVitroInVivoCorrelation.AffineTimeLinearModel, Float64}(InVitroInVivoCorrelation.AffineTimeLinearModel(0.9903218288900248, 0.001064377444093495, 0.8422821450106551, -0.08189413035851242), ["FormC", "FormA"], Symbol[], 1.0, 1.0)Step 5: Predict absorption from dissolution
predict_rate applies the fitted model to every dissolution formulation that was not used in the fit — here the held-out FormB and the dissolution-only FormD — and returns one (; formulation, time, pred_rate, pred_fraction_absorbed) NamedTuple per formulation with the predicted absorption rate and fraction absorbed over time.
pred_profiles = predict_rate(model, diss_df)
[p.formulation for p in pred_profiles]2-element Vector{String}:
"FormD"
"FormB"run_ivivc goes two steps further: it convolves each predicted rate with the subjects' UIRs (convolve) to obtain predicted concentrations, and scores the held-out formulation with compute_prediction_errors.