Skip to content

Commit

Permalink
feat(pm4py): insert lifecycle-based E2O relations in OCEL
Browse files Browse the repository at this point in the history
  • Loading branch information
fit-alessandro-berti committed Mar 23, 2023
1 parent d4a5525 commit 0bb0bad
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
2 changes: 1 addition & 1 deletion pm4py/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
conformance_log_skeleton
from pm4py.ocel import ocel_objects_interactions_summary, ocel_temporal_summary, ocel_objects_summary, ocel_get_object_types, ocel_get_attribute_names, ocel_flattening, ocel_object_type_activities, ocel_objects_ot_count, \
discover_ocdfg, discover_oc_petri_net, discover_objects_graph, sample_ocel_objects, ocel_drop_duplicates, ocel_merge_duplicates, ocel_sort_by_additional_column, \
ocel_add_index_based_timedelta, sample_ocel_connected_components, ocel_o2o_enrichment
ocel_add_index_based_timedelta, sample_ocel_connected_components, ocel_o2o_enrichment, ocel_e2o_lifecycle_enrichment
from pm4py.vis import view_petri_net, save_vis_petri_net, view_dfg, save_vis_dfg, view_process_tree, \
save_vis_process_tree, \
view_ocdfg, save_vis_ocdfg, view_heuristics_net, save_vis_heuristics_net, view_bpmn, save_vis_bpmn, view_sna, save_vis_sna,\
Expand Down
45 changes: 45 additions & 0 deletions pm4py/objects/ocel/util/e2o_qualification.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from pm4py.objects.ocel.obj import OCEL
from typing import Optional, Dict, Any
from enum import Enum
from pm4py.util import exec_utils
from copy import copy

class Parameters(Enum):
CONCATENER = "concatener"
CONCAT_COLUMN = "concat_column"


def apply(ocel: OCEL, qualifier_type: str, parameters: Optional[Dict[Any, Any]] = None) -> OCEL:
if parameters is None:
parameters = {}

concatener = exec_utils.get_param_value(Parameters.CONCATENER, parameters, "@@")
concat_column = exec_utils.get_param_value(Parameters.CONCAT_COLUMN, parameters, "@@concat")

ocel = copy(ocel)
ocel.relations[concat_column] = ocel.relations[ocel.event_id_column] + concatener + ocel.relations[ocel.object_id_column]
relations = ocel.relations.groupby(ocel.object_id_column)[ocel.event_id_column]

if qualifier_type == "creation":
relations = relations.first().to_dict()
relations = {y + concatener + x: qualifier_type for x, y in relations.items()}
elif qualifier_type == "termination":
relations = relations.last().to_dict()
relations = {y + concatener + x: qualifier_type for x, y in relations.items()}
elif qualifier_type == "other":
relations0 = relations.agg(list).to_dict()
relations0 = {x: y[1:-1] for x, y in relations0.items()}
relations0 = {x: y for x, y in relations0.items() if y}
relations = {}
for x, y in relations0.items():
for y1 in y:
relations[y1 + concatener + x] = qualifier_type

ocel.relations[ocel.qualifier+"_2"] = ocel.relations[concat_column].map(relations)
ocel.relations[ocel.qualifier+"_2"] = ocel.relations[ocel.qualifier+"_2"].fillna(ocel.relations[ocel.qualifier])
ocel.relations[ocel.qualifier] = ocel.relations[ocel.qualifier+"_2"]

del ocel.relations[ocel.qualifier+"_2"]
del ocel.relations[concat_column]

return ocel
23 changes: 23 additions & 0 deletions pm4py/ocel.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,29 @@ def ocel_o2o_enrichment(ocel: OCEL, included_graphs: Optional[Collection[str]] =
return ocel20_computation.apply(ocel, parameters={"included_graphs": included_graphs})


def ocel_e2o_lifecycle_enrichment(ocel: OCEL) -> OCEL:
"""
Inserts lifecycle-based information (when an object is created/terminated or other types of relations)
in the list of E2O relations of the OCEL
:param ocel: object-centric event log
:rtype: ``OCEL``
.. code-block:: python3
import pm4py
ocel = pm4py.read_ocel('trial.ocel')
ocel = pm4py.ocel_e2o_lifecycle_enrichment(ocel)
print(ocel.relations)
"""
from pm4py.objects.ocel.util import e2o_qualification
ocel = e2o_qualification.apply(ocel, "termination")
ocel = e2o_qualification.apply(ocel, "creation")
ocel = e2o_qualification.apply(ocel, "other")
return ocel


def sample_ocel_objects(ocel: OCEL, num_objects: int) -> OCEL:
"""
Given an object-centric event log, returns a sampled event log with a subset of the objects
Expand Down

0 comments on commit 0bb0bad

Please sign in to comment.