Skip to content

init

lambda_rules ¤

Lambda-rule subsystem — declarative, YAML-driven detectors that share all canonical-event-log plumbing with the 290 built-in detector methods.

Typical use::

from ts_shape.eventlog import register_lambda_rule, RuleSpec, TriggerSpec

spec = RuleSpec(
    id="high_torque",
    class_name="LambdaToolWear",
    method_name="high_torque",
    pack="maintenance",
    shape="point",
    archetype="threshold",
    template="maintenance.tool.high_torque",
    trigger=TriggerSpec(expression="torque > 75 & state == 'run'"),
    standard_attrs={
        "ts_shape:method": "lambda_threshold",
        "ts_shape:direction": "above",
        "ts_shape:threshold_high": 75.0,
    },
)
detector = register_lambda_rule(spec)
log = detector.to_event_log(df)

See :doc:/guides/lambda-rules for the full walkthrough including a threshold case and an interval-with-hysteresis case.

LambdaDetector ¤

LambdaDetector(spec: RuleSpec)

Runnable form of a :class:RuleSpec.

evaluate ¤

evaluate(df: DataFrame) -> pd.DataFrame

Apply the rule to df and return a legacy-shaped DataFrame.

UnsafeExpression ¤

Bases: ValueError

Raised when a trigger expression contains a disallowed AST node.

RuleSpec dataclass ¤

RuleSpec(
    id: str,
    class_name: str,
    method_name: str,
    pack: str,
    shape: str,
    archetype: str,
    template: str,
    trigger: TriggerSpec,
    produces_objects: tuple[str, ...] = ("asset",),
    severity_field: str | None = None,
    value_field: str | None = None,
    standard_attrs: Mapping[str, object] = dict(),
)

A complete lambda-rule definition.

Required fields mirror the built-in REGISTRY contract — class_name is synthesized (must start with Lambda) so the rule slots into the same (class, method) -> LabelRule table as the 290 built-ins.

TriggerSpec dataclass ¤

TriggerSpec(
    expression: str,
    min_duration_s: float | None = None,
    group_by: tuple[str, ...] = (),
)

When does the rule fire?

expression is evaluated against the input DataFrame by the AST-restricted compiler in :mod:.expression. It must produce a boolean Series aligned with the input rows.

min_duration_s and group_by are only meaningful for shape="interval" rules: consecutive True rows are coalesced (per group) and the resulting interval is dropped if shorter than min_duration_s seconds.

run_backtest ¤

run_backtest(
    detector: LambdaDetector,
    df: DataFrame,
    *,
    objects: Mapping[str, object] | None = None,
    qualifiers: Mapping[str, str] | None = None
) -> BacktestResult

Run detector over df and summarize hit counts.

compile_expression ¤

compile_expression(
    expression: str,
) -> Callable[[pd.DataFrame], pd.Series]

Compile a trigger expression to a vectorized boolean mask function.

The returned callable accepts a :class:pandas.DataFrame and returns a :class:pandas.Series of booleans (NaN → False) aligned with the frame's rows.

load_dicts ¤

load_dicts(
    entries: Iterable[Mapping[str, Any]],
) -> list[LambdaDetector]

Compile + register an iterable of dict rules.

load_yaml ¤

load_yaml(path: str | Path) -> list[LambdaDetector]

Load and register every rule under a YAML file's rules: key.

YAML is imported lazily so :mod:ts_shape.eventlog does not gain a hard runtime dependency on PyYAML for users who only use built-in detectors. Install pyyaml to enable this loader.

register_lambda_rule ¤

register_lambda_rule(spec: RuleSpec) -> LambdaDetector

Register spec in REGISTRY + ARCHETYPE_BY_METHOD; return runnable detector.

Raises :class:ValueError if the spec is malformed, the standard_attrs mapping uses unknown keys, the archetype's required keys are missing, or a rule with the same (class_name, method_name) is already registered.

unregister_lambda_rule ¤

unregister_lambda_rule(
    class_name: str, method_name: str
) -> None

Remove a rule previously installed by :func:register_lambda_rule.

Used by tests to keep the global REGISTRY clean between cases. No-op if the rule was not registered.