name: op-overlay-formula
kind: operator
category: OVERLAY
operator: OVERLAY_FORMULA
description: Expression-driven projection computed via expr-lang against a per-host-shape variable namespace.
type: reference
applies_to: process, compose
examples_tags: [overlay, feature-engineering]
Overlays decorate the host; no Response.Components.
Use when
Computes a custom figure for every cell, group or total from an expression over the value and its margins, totals or prior point.
Questions it answers:
- Can I show each cell as its gap from the row margin divided by the grand total?
- Can I flag each month whose value is more than 10% above the prior month?
Use something else:
ATTR_FORMULAwhen you need a derived field on every row before aggregation.
Params
Scope required — cell (MATRIX) / group (SERIES) / total (SCALAR). params.formula required — an expr-lang/expr expression. params.baseline_position (int, optional) — SERIES only, opts in the baseline variable.
Host shape
ANY shape. Per-shape namespace via types.FormulaNamespace:
- MATRIX:
cell,margin_row|col|grand,sd_row|col|grand(+ref_cellon Compose). - SERIES:
value,total,prior(+ opt-inbaseline,ref_valueon Compose). - SCALAR:
value(+refon Compose).
Output
Shape matches host; each evaluation yields one float64. Layer Baseline unset.
Gotchas
- Compile-once / run-many via
expr.Compile. - Predict-time AST walk validates identifiers; unknown →
PULSE_OVERLAY_FORMULA_INVALID_IDENT+ allowed set. - Parse error →
PULSE_OVERLAY_FORMULA_PARSE_ERROR; non-coercible result →PULSE_OVERLAY_FORMULA_TYPE_MISMATCH. - Embedder
ExprFunctionswiden the function surface; variables are fixed per host shape (widen via a customOverlayKindsentry).lookup(...)needs a registered LookupTable. - Built-ins: scalar
sqrt/log/exp/powand the set helpers; the vector functions (vmean,dot, …) arePULSE_OVERLAY_FORMULA_INVALID_IDENTon predict (request and Compose hosts) and runtime. total(expr)is a formula-attribute-only function: calling it here (Compose host included) isPULSE_FORMULA_TOTAL_SITEon predict and runtime. Use thetotalvariable (SERIES) instead.- Buffered at v1 (margins / totals / SDs need post-fold state).
See
- Skills:
overlay-system,op-attr-formula;docs/src/internals/extension-points.md.