For the complete documentation index, see llms.txt. This page is also available as Markdown.

Twin

Digital twins: forecast, simulate, intervene, score, update.

Twin

A digital twin handle bound to one version (the latest unless told otherwise).

Properties

  • id (str)

  • name (str)

  • kind (str)

  • is_panel (bool)

  • is_temporal (bool)

  • versions (list[dict[str, Any]])

  • version (dict[str, Any])

  • version_id (str)

  • source (Any): The raw source backing this version, or None when it trains off a dataset.

  • graph (Graph)

  • roles (dict[str, Any]): The version's variable roles: which variables are sources and which are targets.

  • update_eligibility (dict[str, Any]): Whether update() would find new data, and whether it can assimilate incrementally.

  • environments (pd.DataFrame): Panel twins: the environments in the version's data, with sample sizes.

  • groups (list[Group]): The twin's saved environment groups — the same ones the platform's picker lists.

Twin.at_version

Undocumented; the signature above is the contract.

Twin.delete

Delete this twin permanently: models, versions, runs and record.

Running discovery or simulation workflows are cancelled first. There is no undo — the platform's own delete confirmation exists for a reason. Requires the digital-twins:delete scope.

This twin version's page on the platform, as a clickable URL.

Twin.discover

Run causal discovery on this version and return the discovered graph.

Parameter
Type
Default
Description

webhook_url

str | None

None

Called with the job result instead of waiting on it.

timeout

float

3600.0

Seconds to wait for the discovery job.

Returns (Graph): The discovered Graph.

Twin.train

Train the model for this version, blocking until done.

An already-trained version is returned as-is: the platform's lifecycle retrains through a new version, not by re-fitting in place. To rebuild a model from scratch (after an engine fix, or a corrupt artifact), use rc.discover(df, force=True) and train the fresh twin it returns.

Parameter
Type
Default
Description

webhook_url

str | None

None

Called with the job result instead of waiting on it.

timeout

float

7200.0

Seconds to wait for the training job.

Returns (Twin): This twin, trained. An already-trained version comes back unchanged.

Twin.run_pipeline

Discovery + dependencies + roles + training in one pass.

Parameter
Type
Default
Description

webhook_url

str | None

None

Called with the job result instead of waiting on it.

timeout

float

7200.0

Seconds to wait for the whole pipeline.

Returns (Twin): This twin, trained.

Twin.evaluate

Undocumented; the signature above is the contract.

Twin.new_version

Derive a fresh, untrained version from an existing one — the retrain primitive.

Inherits the base version's configuration and causal graph, resets every training output, and returns the twin pinned to the new version.

Parameter
Type
Default
Description

bump

str

'patch'

Which part of the version number to advance: patch, minor, or major.

base_version_id

str | None

None

Version to derive from. Defaults to the latest.

dataset_id

str | None

None

Train the new version off a different dataset.

Returns (Twin): A handle bound to the new, untrained version.

Twin.retrain

Create a new version off the latest and train it — the full retrain in one call.

Parameter
Type
Default
Description

bump

str

'patch'

Which part of the version number to advance: patch, minor, or major.

timeout

float

7200.0

Seconds to wait for the training job.

Returns (Twin): A handle bound to the newly trained version.

Twin.set_roles

Set the version's variable roles ahead of discovery and training.

Roles steer the causal engine: targets are the outcomes the model is for, sources are the levers. Pass either list to change just that side — the other keeps its current (or suggested) value. This is the per-version counterpart of the ontology-level concept.override(suggested_role=...), which sets the default for every future twin built over that concept.

Parameter
Type
Default
Description

targets

list[str] | None

None

Outcome variables.

sources

list[str] | None

None

Driver variables.

Returns (dict[str, Any]): The stored roles document.

Twin.update

Fold data added to the backing source since the last train/update into the model.

No retrain: incremental assimilation. The job succeeds with a status rather than failing — committed, up_to_date, or retrain_required (the model can't take these rows incrementally; result.reasons says why — call retrain()). Static and temporal twins assimilate out of the box; panel twins need the v2 panel engine. Requires a trained version; extend or sync the source first so there is something new.

Parameter
Type
Default
Description

webhook_url

str | None

None

Called with the job result instead of waiting on it.

timeout

float

3600.0

Seconds to wait for the update job.

Returns (UpdateResult): An UpdateResult. Never raises on retrain_required.

Twin.env

A handle pinned to a subset of this panel twin's environments.

Name them directly — environment names ("london"), envKeys, or exact {column: value} combos — or select them by data with where=, filtering on any twin column through per-environment statistics:

One saved environment group, by name or id.

Parameter
Type
Default
Description

name_or_id

str

required

The group's display name (case-insensitive) or its id.

Returns (Group): A Group: the same scoped surface as env(), pinned to a saved membership rule.

Raises

  • RootCauseError: The twin has no such group; the message names the ones it does have.

Twin.score

Score rows against target outcomes: each row gets its smallest flip.

Static trained twins only. Blocks until the run completes.

Parameter
Type
Default
Description

rows

pd.DataFrame | list[dict[str, Any]]

required

A DataFrame, or a list of dicts whose keys name twin variables.

targets

list[dict[str, Any]]

required

The outcomes to reach, as [{"variable": ..., "value": ...}].

max_changes

int

3

Most variables any one row is allowed to flip.

constraints

dict[str, Any] | None

None

Per-variable limits on what may change, and how far.

webhook_url

str | None

None

Called with the run result instead of waiting on it.

timeout

float

3600.0

Seconds to wait for the run.

Returns (ScoreResult): A ScoreResult covering every row.

Twin.sample

Raw joint posterior draws — the primitive every simulation family wraps.

Parameter
Type
Default
Description

n

int

1000

Draws per sampling unit.

do

dict[str, Any] | None

None

Interventions to apply before sampling, as {"variable": rc.set(value)}. A bare value means rc.set.

where

Any

None

Scope the draws to a subpopulation: {"region": "EMEA"} for equality, or {"income": ("<", 5000)} with any of == != > < >= <=, plus in and not_in.

environments

list[str] | None

None

Panel twins: which environments to sample. Each is sampled independently.

seed

int | None

None

Seed for reproducible draws. Panel twins derive stable per-environment child seeds from it.

Returns (SampleDraws): The draws as SampleDraws.

Raises

  • RootCauseError: environments was passed for a twin that is not a panel twin.

Twin.intervene

Run an intervention simulation and block for the result.

Interventions measure their effect through metrics: pass metrics=[rc.metric(...)] for full control, or outcomes=["revenue"] for mean-of-column metrics. For raw effect distributions without metrics, use twin.sample(do=...).

Parameter
Type
Default
Description

do

dict[str, Any]

required

The interventions, as {"variable": rc.set(value)}. A bare value means rc.set; rc.range(...) sweeps instead of pinning.

where

Any

None

Scope the intervention to a subpopulation: {"region": "EMEA"} for equality, or {"income": ("<", 5000)} with any of == != > < >= <=, plus in and not_in.

metrics

list[dict[str, Any]] | None

None

Metrics to measure the effect through, from rc.metric().

outcomes

list[str] | None

None

Column names to measure as mean-of-column metrics, when metrics is not given.

environments

list[str] | None

None

Panel twins: which environments to simulate.

timeout

float

3600.0

Seconds to wait for the run.

Returns (SimulationResult): A SimulationResult.

Raises

  • RootCauseError: Neither metrics nor outcomes was given.

Twin.forecast

Forecast horizon steps ahead for the target variables.

Parameter
Type
Default
Description

horizon

int

required

How many steps ahead to forecast.

targets

list[str] | None

None

Variables to forecast. Inferred from the twin when omitted.

environments

list[str] | None

None

Panel twins: which environments to forecast.

confidence

float

0.95

Width of the prediction interval, as a probability.

origin_timestamp

int | None

None

Anchor the forecast start (ms epoch). How a backtest aligns a forecast against data the twin never saw.

aggregate

str | None

None

Panel twins: add a combined series across environments, one of sum, avg, min, max.

timeout

float

3600.0

Seconds to wait for the run.

Returns (ForecastResult): A ForecastResult, tidy long format.

Raises

  • RootCauseError: The twin is not temporal, or aggregate was passed for a twin that is not a panel twin.

Twin.predict

Predict target outcomes for input records, with uncertainty intervals.

One prediction per input record: the model reads the values you supply as the drivers and answers for the targets you name. Static twins only: a temporal twin projects forward with forecast() instead.

Parameter
Type
Default
Description

sample

pd.DataFrame | list[dict[str, Any]]

required

The input records, as a DataFrame or a list of dicts keyed by twin variable name. Leave the target columns out: those are what the model answers with.

targets

list[str] | None

None

Variables to predict. Inferred from the twin when omitted.

confidence

float

0.95

Width of the uncertainty interval, as a probability.

timeout

float

3600.0

Seconds to wait for the run.

Returns (PredictionResult): A PredictionResult, one row per input record.

Raises

  • RootCauseError: The twin is temporal, where forecast() is the verb.

Examples

Twin.explain

Explain a causal relationship: what a variable drives, or what drives it.

The mode follows from what you name, so you rarely pass it: cause= alone asks what that variable goes on to affect (impact), effect= alone asks what drives it (discovery), and both together explain the paths from one to the other (directional).

Parameter
Type
Default
Description

cause

str | None

None

The upstream variable, for impact and directional.

effect

str | None

None

The downstream variable, for discovery and directional.

mode

str | None

None

Override the mode: directional, discovery, or impact.

environments

list[str] | None

None

Panel twins: which environments to explain.

timeout

float

3600.0

Seconds to wait for the run.

Returns (SimulationResult): A SimulationResult.

Raises

  • RootCauseError: Neither variable was named, the mode is unknown, the mode is missing a variable it needs, or environments was passed for a twin that is not a panel twin.

Examples

Twin.optimise

Search for the actions that best move your objectives.

The optimizer may only touch the variables you list in decision_vars, and it measures every plan through the objectives' SQL, so an objective naming a variable nothing in decision_vars can reach has no plan to find.

Parameter
Type
Default
Description

objectives

list[dict[str, Any]]

required

What to move and which way, from rc.objective().

decision_vars

list[str]

required

The variables the optimizer is allowed to change.

horizon

int | None

None

Temporal twins: how many steps ahead the plan runs over. Required for a temporal twin, refused for a static one.

environments

list[str] | None

None

Panel twins: which environments to optimize over.

variable_constraints

list[dict[str, Any]] | None

None

Bounds on how far each variable may move.

metric_constraints

list[dict[str, Any]] | None

None

Guardrails every plan must respect.

max_changes

int | None

None

Cap on how many variables a single plan may change.

timeout

float

3600.0

Seconds to wait for the run.

Returns (SimulationResult): A SimulationResult.

Raises

  • RootCauseError: No objectives or no decision variables, an objective that is not a rc.objective() payload, a horizon that this twin kind does not take (or a temporal twin given none), or environments on a twin that is not a panel twin.

Examples

Twin.root_cause

Diagnose one variable: trace it upstream to what actually broke it.

Use this when you already know which variable is misbehaving. To find out whether anything is, scan every variable with anomalies().

Parameter
Type
Default
Description

target

str

required

The variable behaving unexpectedly.

samples

pd.DataFrame | list[dict[str, Any]] | dict[str, list[dict[str, Any]]]

required

The observations to diagnose, as a DataFrame, a list of dicts, or, on a panel twin, a {environment: rows} mapping. A flat list on a panel twin is shared across its environments.

environments

list[str] | None

None

Panel twins: which environments to diagnose.

timestep

int | None

None

Temporal twins: the step to diagnose. Defaults to the one the scan flags.

target_fpr

float

0.005

Detection sensitivity, as a false-positive rate between 0.0001 and 0.1. Lower flags less.

timeout

float

3600.0

Seconds to wait for the run.

Returns (SimulationResult): A SimulationResult.

Raises

  • RootCauseError: No target, environments or per-environment samples on a twin that is not a panel twin, or timestep on a twin with no time axis.

Examples

Twin.anomalies

Scan every variable for causal anomalies, and diagnose what it finds.

The counterpart to root_cause(): this one asks whether anything is broken rather than why a named variable is.

Parameter
Type
Default
Description

samples

pd.DataFrame | list[dict[str, Any]] | dict[str, list[dict[str, Any]]]

required

The observations to scan, as a DataFrame, a list of dicts, or, on a panel twin, a {environment: rows} mapping. A flat list on a panel twin is shared across its environments.

environments

list[str] | None

None

Panel twins: which environments to scan.

start_step

int | None

None

Temporal twins: first step of the window to scan.

end_step

int | None

None

Temporal twins: last step of the window to scan.

target_fpr

float

0.005

Detection sensitivity, as a false-positive rate between 0.0001 and 0.1. Lower flags less.

timeout

float

3600.0

Seconds to wait for the run.

Returns (SimulationResult): A SimulationResult.

Raises

  • RootCauseError: environments or per-environment samples on a twin that is not a panel twin, or a step window on a twin with no time axis.

Examples

Twin.ask

Natural-language question, turned into a scenario and executed.

Parameter
Type
Default
Description

query

str

required

The question, in plain language.

timeout

float

3600.0

Seconds to wait for the run.

Returns (SimulationResult): A SimulationResult; result.scenario is what the translator produced.

Twin.console

The interactive causal-graph console under the cell: the same app Claude renders.

Explore edges, type intervention values, and re-run scenarios; every control round-trips live through the platform's MCP gateway with this session's credentials. Needs: pip install "rootcause-sdk[jupyter]".

Parameter
Type
Default
Description

height

int

560

Height of the mounted app, in pixels.

theme

str

''

light, dark, or empty to follow the notebook.

Returns (Any): The mounted widget, displayed by the notebook cell.

Twin.sankey

The causal-flow Sankey under the cell: how influence propagates through the graph.

Pass a variable to see everything flowing into and out of it, or an edge to see the paths running through that one link. Needs a resolved or trained graph and: pip install "rootcause-sdk[jupyter]".

Parameter
Type
Default
Description

node

str | None

None

Variable to analyse paths around. Exactly one of node and edge must be given.

edge

tuple[str, str] | None

None

A (cause, effect) pair to analyse paths through.

depth

int

2

How many hops to traverse on either side.

height

int

520

Height of the mounted app, in pixels.

theme

str

''

light, dark, or empty to follow the notebook.

Returns (Any): The mounted widget, displayed by the notebook cell.

Twin.review

The graph-review console under the cell: structural findings with accept/reject controls.

Runs the platform's DAG review (cycles, isolated nodes, weak or wrong-direction edges, over-connected hubs) and mounts the interactive console over the findings; applying a fix round-trips live through the MCP gateway. Needs: pip install "rootcause-sdk[jupyter]".

Parameter
Type
Default
Description

height

int

560

Height of the mounted app, in pixels.

theme

str

''

light, dark, or empty to follow the notebook.

Returns (Any): The mounted widget, displayed by the notebook cell.

Twin.studio

Ask a what-if in plain English; the What-If Studio renders the answer under the cell.

The scenario is inferred from the question and executed server-side; the studio draws the result with the dials behind it, so a tweaked scenario re-runs live through the MCP gateway without leaving the notebook. Needs: pip install "rootcause-sdk[jupyter]".

Parameter
Type
Default
Description

query

str

required

The question, stated completely — which variables change, to what, and the outcome of interest.

targets

list[str] | None

None

Exact outcome variable names, when inference should not pick them from the question.

horizon

int | None

None

Forecast scenarios only: exact number of steps.

environments

list[str] | None

None

Panel forecasts only: restrict to these environments.

aggregate

str | None

None

Panel forecasts only: sum, avg, min, or max across environments.

height

int

640

Height of the mounted app, in pixels.

theme

str

''

light, dark, or empty to follow the notebook.

Returns (Any): The mounted widget, displayed by the notebook cell.

Twin.save

Export this twin (trained params included) as a portable .rctwin zip.

Parameter
Type
Default
Description

path

str | Path

required

Where to write the .rctwin file. A directory writes <twin name>.rctwin inside it.

include_runs

bool

False

Include the simulation run history in the export.

timeout

float

3600.0

Seconds to wait for the export job.

Returns (Path): The path written, ready for rc.load_twin().

Raises

  • InvalidArgumentError: The destination directory does not exist. The check runs before the export job starts.

EnvSubset

A panel twin pinned to a subset of its environments.

Everything on the handle runs scoped to the subset: graph re-aggregates the causal adjacency over just these environments, and sample/intervene/ forecast delegate to the twin with environments= filled in.

Properties

  • environments (pd.DataFrame): The environments this handle covers, resolved to a DataFrame.

  • graph (pd.DataFrame)

EnvSubset.combos

The subset as exact {column: value} combos, resolved against the twin's environments.

The listing carries each environment's values as a list ordered by environmentColumns; zipping the two recovers the combo.

EnvSubset.save

Save this subset on the twin as a named environment group.

The group lives on the twin rather than on a version, so it survives retraining, appears in the platform's environment picker straight away, and comes back next session as twin.group(name). What gets stored is the rule, not the answer: a where= subset saves its filters and re-selects environments as the data moves, while a named subset saves the exact combos it resolved to.

Parameter
Type
Default
Description

name

str

required

Display name, unique per twin.

Returns (Group): The saved Group.

Raises

  • RootCauseError: The twin already has a group with this name, or is at its group cap.

EnvSubset.adjacency

The causal adjacency aggregated over just this subset of environments.

Returns the edges as a DataFrame (source, target, strength, agreementRate, …); frame.attrs carries envCount, sampleSize, totalEnvCount, and the threshold.

EnvSubset.sample

Undocumented; the signature above is the contract.

EnvSubset.intervene

Undocumented; the signature above is the contract.

EnvSubset.forecast

Undocumented; the signature above is the contract.

EnvSubset.explain

Undocumented; the signature above is the contract.

EnvSubset.optimise

Undocumented; the signature above is the contract.

EnvSubset.root_cause

Undocumented; the signature above is the contract.

EnvSubset.anomalies

Undocumented; the signature above is the contract.

The parent twin's page on the platform, as a clickable URL.

Group

A saved environment group: the same scoped surface as a subset, kept on the twin.

Everything an EnvSubset does, a group does against its current membership — the rule is stored, not the answer, so it is resolved against this handle's version on first use and re-resolved after an edit. Simulations name the group rather than expanding it, so the run records which group it covered and what that meant at submit time.

Attribute
Type
Description

doc

dict

The stored group document.

Properties

  • id (str)

  • name (str)

  • definition (dict[str, Any]): The stored membership rule: environments, columnValues, or statFilters mode.

Group.rename

Rename the group in place.

Parameter
Type
Default
Description

name

str

required

The new display name, unique per twin.

Returns (Group): This group.

Raises

  • RootCauseError: The twin already has a group with this name.

Group.update

Replace the group's membership rule, in the same vocabulary as twin.env().

Runs already submitted keep the membership frozen on their snapshots; every later read of the group sees the new rule.

Parameter
Type
Default
Description

*environments

str | dict[str, str]

()

Environment names, envKeys, or {column: value} combos, as env() takes them.

where

list[tuple] | dict[str, Any] | None

None

Stat filters instead of names, as env() takes them.

definition

dict[str, Any] | None

None

A raw definition document, when you have one already.

Returns (Group): This group, on the new rule.

Raises

  • RootCauseError: None (or more than one) of the three selection styles was passed.

Group.delete

Delete the group from the twin.

Nothing downstream goes with it: runs scoped to the group keep their snapshots. Deleting a group that is already gone is a no-op.

Group.intervene

Undocumented; the signature above is the contract.

Group.forecast

Undocumented; the signature above is the contract.

Group.explain

Undocumented; the signature above is the contract.

Group.optimise

Undocumented; the signature above is the contract.

Group.root_cause

Undocumented; the signature above is the contract.

Group.anomalies

Undocumented; the signature above is the contract.

The parent twin's page on the platform, as a clickable URL.

Last updated