Sia forecasts survival endpoints, such as progression-free and overall survival, in an ongoing trial from the data collected so far. It links each patient's disease burden to progression, death and leaving the trial in one Bayesian analysis. The forecasts in the case studies on this site were produced with Sia.
Fit the data up to an interim cut-off and simulate the rest of the trial. Sia removes data after the cut-off before it builds the model. It can simulate each enrolled patient from their own record, or simulate new patients from the population.
Use the posterior from earlier trials in the same indication as the prior for a new one. Sia estimates how much to widen that prior for each group of parameters, so it borrows less when the trials disagree.
Write a declaration with the indication's states, markers and assessment schedules. The four case studies on this site are four declarations. The pancreatic model uses tumor size and CA19-9. The prostate model has separate schedules for imaging and PSA.
Score forecasts made at earlier cut-offs against the data that came after them. Run prior predictive simulations and prior sensitivity analyses. Sia refuses a declaration, prior or dataset it cannot fit, and names the entry at fault.
Sia works from the patient-level data a trial already collects. It returns the range of results the trial could still report, with a probability for each.
The inputs, the fitted model and the outputs belong to the client. The fitted model is the posterior for every parameter, learned from the client's data, and zahrcast does not use it for other clients. The Sia platform remains the property of zahrcast. The client's fitted model runs on the platform, and every output is produced from it there.
Every number is read off thousands of simulated completed trials. How the simulations work.
A mechanistic submodel describes each patient's disease burden over time. A multistate submodel describes the transitions to progression, death and leaving the trial, with the burden as an input. The two are fitted together.
Models of this kind are called joint models for longitudinal and time-to-event data.1–4 When a joint model is fitted to a patient's measurements so far, its predictions for that patient update as new measurements arrive.5 In oncology, nonlinear models of tumor size or PSA have been linked to survival in colorectal, lung, prostate and bladder cancer.6–9 Bruno and colleagues review these tumor dynamic models.10 A model with several event states, such as progression and death, is a multistate model.11 Earlier work has joined multistate models to longitudinal measurements12 and used them to model progression-free and overall survival together.13
Progression-free and overall survival come from the same simulated trials, so they are consistent with each other. The diagram is redrawn from the ES-SCLC manuscript,14 without the mathematical notation.
Each patient's burden follows a bi-exponential curve that extends the form of Stein and colleagues:15 a shrinking part declines while a growing part regrows.
Sia estimates how much to borrow from historical trials. When they disagree, it borrows less. Related methods include power priors, commensurate priors and robust meta-analytic-predictive priors.16–18
A new indication usually needs new priors and data handling rather than changes to Sia's core code.
Forecasts are scored against data that arrived after their cut-off. This is leave-future-out validation.19
Sia is written in Julia.20 Its statistical code is written in Turing.jl21 and fitted with the No-U-Turn sampler, a form of Hamiltonian Monte Carlo.22 These are open-source tools, so a client's statistician can check how the fitting works.
A Sia model is written as a declaration. It lists the states a patient can occupy, the transitions between them, the markers that are measured and the groups patients belong to. Sia builds, fits and checks the model from that declaration, and forecasts from it.
The example below declares a joint model for small-cell lung cancer. It has two markers, tumor size on imaging and circulating tumor DNA (ctDNA), five states and endpoints for progression-free and overall survival. It shows the form of a declaration. The SCLC case study on this site used a different model, without ctDNA.
using Sia
# Smooth, time-varying baseline hazards on a four-week grid
const CALENDAR = (shape = :gaussian_process, knot_spacing = 4, knots_until = 200, between_knots = :hold)
const AFTER_PD = (shape = :gaussian_process, knot_spacing = 4, knots_until = 108, between_knots = :hold)
const OFF_TX = (shape = :gaussian_process, knot_spacing = 4, knots_until = 24, between_knots = :hold)
sclc = Sia.@model_config begin
@burden begin
rates => (shrink = (levels = (trial = :re, arm = :re), covariates = ~ ecog + ldh,
coupling_centre = -2.2),
regrowth = (levels = (trial = :re, arm = :re), covariates = ~ ecog + ldh,
coupling_centre = -3.7))
shrinking_fraction => (levels = (arm = :re,),)
regrowth_slowdown => (levels = (arm = :re,),)
reference = :sld
@markers begin
sld => (obs_noise = :student_t,)
ctdna => (elasticity = :estimated, baseline_window = 2.0, obs_noise = :student_t,
baseline = (levels = (arm = :re,), covariates = ~ ecog))
end
end
@states begin
0 => "on treatment"
1 => "progressed"
2 => "dead"
3 => "lost to follow-up"
4 => "discontinued"
end
@transitions begin
0 → 1 => (detection = :at_visits, burden_coupling = :interpolated,
deterministic_cause = :recist,
trend = (shape = :logtime, centred_until = 200),
baseline = (curve = CALENDAR, beyond_knots = :extend),
covariates = ~ age + ecog,
levels = (arm = (intercept = :re, trend = :re, curve = CALENDAR),))
0 → 2 => (detection = :exact, burden_coupling = :none,
baseline = (curve = CALENDAR, beyond_knots = :extend),
covariates = ~ age + ecog + ldh,
levels = (arm = (intercept = :re, curve = CALENDAR),))
1 → 2 => (detection = :exact, burden_coupling = :none, clock = :sojourn,
baseline = (curve = AFTER_PD, beyond_knots = :extend),
levels = (arm = (intercept = :re, curve = AFTER_PD),))
0 → 3 => (detection = :at_visits, burden_coupling = :interpolated,
baseline = (curve = CALENDAR, beyond_knots = :extend),
levels = (arm = (intercept = :re, curve = CALENDAR),))
0 → 4 => (detection = :exact, burden_coupling = :last_scan,
baseline = (curve = CALENDAR, beyond_knots = :extend),
levels = (arm = (intercept = :re, curve = CALENDAR),))
4 → 1 => (detection = :at_visits, burden_coupling = :none, clock = :sojourn,
baseline = (curve = OFF_TX, beyond_knots = :extend),
levels = (arm = (intercept = :re, curve = OFF_TX),))
4 → 2 => (detection = :exact, burden_coupling = :none, clock = :sojourn,
baseline = (curve = OFF_TX, beyond_knots = :extend),
levels = (arm = (intercept = :re, curve = OFF_TX),))
end
@frailty begin
(0 → 1, 0 → 3)
end
@levels begin
trial => (groups = :trial,)
arm => (groups = :arm,)
end
@endpoints begin
pfs => (event = (0 → 1, 4 → 1, 0 → 2, 4 → 2),
censoring = (0 → 3,),
irrelevant = (1 → 2, 0 → 4))
os => (event = (0 → 2, 1 → 2, 4 → 2),
censoring = (0 → 3,),
irrelevant = (0 → 1, 4 → 1, 0 → 4))
end
@precedence begin
0 => (0 → 3, 0 → 4, 0 → 1, 0 → 2)
4 => (4 → 1, 4 → 2)
end
end
The burden trajectory, how it varies by trial and arm, and the covariates that shift it. Tumor size (sld) is the reference marker. ctDNA measures the same burden on its own scale.
For each transition: whether it is detected at scheduled scans or on the day it happens, which clock it runs on, and whether the burden enters its hazard.
Progression and loss to follow-up share a patient-level random effect.
Which transitions count as events, censoring or neither for progression-free and overall survival.
How events found at the same visit are ordered. The fit and the forecast use the same order.
The groups patients are pooled across, such as trial and arm.
Sia checks the whole declaration before fitting. If an entry is invalid, Sia stops with a message that names it. Priors are declared in the same way, against the same names. Adding a state, a marker or a level changes the declaration and leaves Sia's code unchanged.
Everything listed here is in Sia's released code. Each modeling choice is set in the model declaration.
Sia has been applied to extensive-stage small-cell lung cancer, metastatic colorectal cancer, metastatic castration-resistant prostate cancer and metastatic pancreatic cancer. Each case study compares forecasts made at interim cut-offs with the survival observed at the trial's final data cut.23
We work with your team to declare a model for your disease, fit it to your trials and deliver the forecasts. Engagement terms are available on request. The Sia source is private.