xbudget.evaluate

Evaluate a typed budget tree against a dataset/grid.

The evaluator walks the xbudget.nodes tree and materializes one output variable per operation (a sum/product/difference), naming it by its structured path with the operator infixes dropped (see _new_name). A term with more than one operation emits one variable each; the first sum/product operation (or a lone operation) claims the bare path name, and any siblings are suffixed with their operator kind.

It is intentionally side-effecting in one place only: it writes the derived variables into the dataset. It never mutates the recipe (the typed tree is immutable). It returns a records map (new variable name -> its path and operation) describing what it built.

Missing diagnostics

A recipe is meant to serve datasets with different diagnostics available, so a term that references an absent variable is skipped rather than fatal. The important thing is that a skip is never silent-and-forgotten: every variable the evaluator emits that was built from fewer inputs than its recipe describes is stamped with xbudget_incomplete and xbudget_missing attributes, which persist to disk and are queryable through xbudget.query.BudgetQuery. This turns “a term is there when it isn’t” into “the term is there and says so.”

Three policies (on_missing) select how loud a missing required diagnostic is: "warn" (default) emits one end-of-run summary; "raise" fails with a MissingDiagnosticError; "ignore" is silent (but still stamps the attributes). A term (or subtree) declared optional in the recipe is exempt from all three — its absence is expected, so it is dropped with no warning, no error, and no incomplete flag on its parent.

A product with a missing required factor is dropped (the term does not materialize) rather than multiplying in 0.0 and emitting an identically-zero variable. An unknown factor is not the same as a zero one; a fabricated zero reads as a real (null) contribution to whatever consumes it. A sum still drops only the missing operand and builds from the rest, flagged incomplete.

Functions

evaluate_budgets(data, budgets[, ...])

Evaluate parsed budgets into data; return records.

Exceptions

MissingDiagnosticError(message, missing)

A required diagnostic was absent under on_missing="raise".