Skip to content
v1.0.3

Discovery

class DiscoveryMethodMeta:
Source
@dataclass
class DiscoveryMethodMeta:
name: str
description: str | None
func: Callable[..., Resource]
resource_type: type[Resource]
def discovery_method(name: str, description: str | None = None) -> Callable[[Callable[..., Resource]], Callable[..., Resource]]:

Mark a function as a discovery method.

Stamps __discovery_meta__ on the function. The backend scans for this attribute at startup, derives the parameter schema from the function signature, and exposes the method through the discovery API.

Source
def discovery_method(
*,
name: str,
description: str | None = None,
) -> Callable[[Callable[..., Resource]], Callable[..., Resource]]:
"""Mark a function as a discovery method.
Stamps `__discovery_meta__` on the function. The backend scans for this
attribute at startup, derives the parameter schema from the function
signature, and exposes the method through the discovery API.
"""
def decorator(func: Callable[..., Resource]) -> Callable[..., Resource]:
hints = get_type_hints(func, include_extras=True)
resource_type = _extract_resource_type(func.__name__, hints.get("return")) # ty: ignore[unresolved-attribute]
func.__discovery_meta__ = DiscoveryMethodMeta( # type: ignore[attr-defined] # ty: ignore[unresolved-attribute]
name=name,
description=description,
func=func,
resource_type=resource_type,
)
return func
return decorator
def inductive_miner(ocel: OCEL, noise_threshold: Annotated[float, Field(ge=0, le=1, title='Noise Threshold', description='Fraction of infrequent behaviour to filter out (0 = no filtering, IMf variant).')] = 0.8) -> PetriNet:
Source
@discovery_method(
name="Inductive Miner (flattening)",
description="Discover an object-centric Petri net with the inductive miner.",
)
def inductive_miner(
ocel: OCEL,
noise_threshold: Annotated[
float,
Field(
ge=0,
le=1,
title="Noise Threshold",
description="Fraction of infrequent behaviour to filter out (0 = no filtering, IMf variant).",
),
] = 0.8,
) -> PetriNet:
ocpn = pm4py.discover_oc_petri_net(
ocel=ocel.ocel,
noise_threshold=noise_threshold,
disable_fallthroughs=False,
disable_strict_sequence_cut=False,
)
return PetriNet.from_pm4py(ocpn)
def ocdfg_miner(ocel: OCEL, frequency_threshold: Annotated[float, Field(ge=0, le=1, title='Frequency Threshold', description='Percentage of edges too keep (1 = keep all). Frequency Values of edges are determined with respect to the absolute count of their object types.')] = 1) -> DirectlyFollowsGraph:
Source
@discovery_method(
name="Object-Centric DFG",
description="Discover an object-centric directly-follows graph.",
)
def ocdfg_miner(
ocel: OCEL,
frequency_threshold: Annotated[
float,
Field(
ge=0,
le=1,
title="Frequency Threshold",
description="Percentage of edges too keep (1 = keep all). Frequency Values of edges are determined with respect to the absolute count of their object types.",
),
] = 1,
) -> DirectlyFollowsGraph:
dfg = DirectlyFollowsGraph.from_pm4py(pm4py.discover_ocdfg(ocel.ocel))
return dfg.filter_edges(1 - frequency_threshold)