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.