diff --git a/code/conformance-checking.py b/code/conformance-checking.py new file mode 100644 index 0000000..a4508de --- /dev/null +++ b/code/conformance-checking.py @@ -0,0 +1,347 @@ +#%% # needed for shortcuts to run properly in VSCode *eyeroll* +%reset + +import pm4py + +import pandas as pd +import numpy as np +import matplotlib.pyplot as plt + +###### Load data and create event logs ###### + +dat = pd.read_csv("results/haum/event_logfiles_2024-01-02_19-44-50.csv", sep = ";") +dat = dat[dat["date.start"] < "2020-03-13"] +# --> only pre corona (before artworks were updated) + +event_log = pm4py.format_dataframe(dat, case_id='path', activity_key='event', + timestamp_key='date.start') +event_log = event_log.rename(columns={'artwork': 'case:artwork'}) + +###### Descrptives of log data ###### + +# Distribution of events +event_log.event.value_counts() +event_log.event.value_counts(normalize=True) + +# Number of paths +len(event_log.path.unique()) + +# Number of variants +variants = pm4py.get_variants(event_log) +len(variants) + +sorted_variants = dict(sorted(variants.items(), key=lambda item: item[1], reverse = True)) +{k: sorted_variants[k] for k in list(sorted_variants)[:20]} + +filtered_log = event_log[event_log["event"] != "move"] +variants = pm4py.get_variants(filtered_log) +len(variants) +sorted_variants = dict(sorted(variants.items(), key=lambda item: item[1], reverse = True)) +{k: sorted_variants[k] for k in list(sorted_variants)[:20]} + +# Path length +event_log.path.value_counts() +event_log.path.value_counts().mean() +event_log.path.value_counts().median() +event_log.path.value_counts().min() +event_log.path.value_counts().max() + +plt.hist(event_log.path.value_counts(), bins=200) +plt.show() + +# TODO: Do it again in R -- much smoother and more info, better plots + +###### Read "conformative" Petri Net ###### + +basenet, initial_marking, final_marking = pm4py.read_pnml("results/conformative_petrinet_con.pnml") + +def eval_pm(data, net, initial_marking, final_marking): + """Caculate fitness, precision, generalizability, and simplicity for petri net""" + fitness = pm4py.fitness_token_based_replay(data, net, initial_marking, final_marking) + precisison = pm4py.precision_token_based_replay(data, net, + initial_marking, final_marking) + generalizability = pm4py.algo.evaluation.generalization.algorithm.apply(data, net, + initial_marking, final_marking) + simplicity = pm4py.algo.evaluation.simplicity.algorithm.apply(net) + return [fitness['average_trace_fitness'], precisison, generalizability, simplicity] + +baseline_eval = eval_pm(event_log, basenet, initial_marking, final_marking) + +# TBR +replayed_traces = pm4py.conformance_diagnostics_token_based_replay(event_log, basenet, initial_marking, final_marking) + +l1 = list() +l2 = list() +l3 = list() +l4 = list() +for i in range(len(replayed_traces)): + l1.append(replayed_traces[i]["remaining_tokens"]) + l2.append(replayed_traces[i]["missing_tokens"]) + l3.append(replayed_traces[i]["reached_marking"]) + l4.append(replayed_traces[i]["transitions_with_problems"]) + +np.mean(l1) +set(l1) +index_broken = l1.index(1) +np.mean(l2) +set(l2) +l2.index(1) +set(l3) +l4.count([]) + +l3[index_broken] +l4[index_broken] + +replayed_traces[index_broken] + +# 216295 # --> broken trace! Must be in artwork 176!!!!! + + +from pm4py.algo.conformance.tokenreplay import algorithm as token_based_replay +parameters_tbr = {token_based_replay.Variants.TOKEN_REPLAY.value.Parameters.DISABLE_VARIANTS: True, token_based_replay.Variants.TOKEN_REPLAY.value.Parameters.ENABLE_PLTR_FITNESS: True} +replayed_traces, place_fitness, trans_fitness, unwanted_activities = token_based_replay.apply(event_log, basenet, + initial_marking, + final_marking, + parameters=parameters_tbr) + +from pm4py.algo.conformance.tokenreplay.diagnostics import duration_diagnostics +trans_diagnostics = duration_diagnostics.diagnose_from_trans_fitness(event_log, trans_fitness) +for trans in trans_diagnostics: + print(trans, trans_diagnostics[trans]) + +# Footprints +from pm4py.algo.discovery.footprints import algorithm as footprints_discovery +fp_log = footprints_discovery.apply(event_log, variant=footprints_discovery.Variants.ENTIRE_EVENT_LOG) + +fp_trace_by_trace = footprints_discovery.apply(event_log, variant=footprints_discovery.Variants.TRACE_BY_TRACE) + +fp_net = footprints_discovery.apply(basenet, initial_marking, final_marking) + +from pm4py.visualization.footprints import visualizer as fp_visualizer +gviz = fp_visualizer.apply(fp_net, parameters={fp_visualizer.Variants.SINGLE.value.Parameters.FORMAT: "svg"}) +fp_visualizer.view(gviz) + +gviz = fp_visualizer.apply(fp_log, fp_net, parameters={fp_visualizer.Variants.COMPARISON.value.Parameters.FORMAT: "svg"}) +fp_visualizer.view(gviz) + +conf_fp = pm4py.conformance_diagnostics_footprints(fp_trace_by_trace, fp_net) + +from pm4py.algo.conformance.footprints import algorithm as fp_conformance +conf_result = fp_conformance.apply(fp_log, fp_net, variant=fp_conformance.Variants.LOG_EXTENSIVE) + +from pm4py.algo.conformance.footprints.util import evaluation +fitness = evaluation.fp_fitness(fp_log, fp_net, conf_result) +precision = evaluation.fp_precision(fp_log, fp_net) + +# Skeleton +from pm4py.algo.discovery.log_skeleton import algorithm as lsk_discovery +skeleton = lsk_discovery.apply(event_log, parameters={lsk_discovery.Variants.CLASSIC.value.Parameters.NOISE_THRESHOLD: 0.0}) + +from pm4py.algo.conformance.log_skeleton import algorithm as lsk_conformance +conf_result = lsk_conformance.apply(event_log, skeleton) + +pm4py.vis.view_petri_net(basenet, initial_marking, final_marking) +is_sound = pm4py.check_soundness(basenet, initial_marking, final_marking) +is_sound[0] +len(basenet.arcs) +len(basenet.transitions) +len(basenet.places) + +efg_graph = pm4py.discover_eventually_follows_graph(event_log) + +## Directly-follows graph +dfg, start_activities, end_activities = pm4py.discover_dfg(event_log) +pm4py.view_dfg(dfg, start_activities, end_activities) +pm4py.save_vis_dfg(dfg, start_activities, end_activities, '../figures/processmaps/dfg_complete.png') + +## Heuristics Miner +h_net, im, fm = pm4py.discover_petri_net_heuristics(event_log) +h_eval = eval_pm(event_log, h_net, im, fm) +pm4py.vis.view_petri_net(h_net, im, fm) +pm4py.vis.save_vis_petri_net(h_net, im, fm, "../figures/processmaps/pn_heuristics_complete.png") + +is_sound = pm4py.check_soundness(h_net, im, fm) +is_sound[0] + +len(h_net.arcs) +len(h_net.transitions) +len(h_net.places) + + +# decorated petri net +from pm4py.visualization.petri_net import visualizer as pn_visualizer +parameters = {pn_visualizer.Variants.FREQUENCY.value.Parameters.FORMAT: "png"} +gviz = pn_visualizer.apply(h_net, im, fm, parameters=parameters, variant=pn_visualizer.Variants.FREQUENCY, log=event_log) +pn_visualizer.save(gviz, "../figures/processmaps/pn_heuristics_complete_decorated.png") + +# convert to BPMN +bpmn = pm4py.convert.convert_to_bpmn(h_net, im, fm) +pm4py.vis.view_bpmn(bpmn) + +## Alpha Miner +a_net, im, fm = pm4py.discover_petri_net_alpha(event_log) +a_eval = eval_pm(event_log, a_net, im, fm) +pm4py.vis.view_petri_net(a_net, im, fm) +pm4py.vis.save_vis_petri_net(a_net, im, fm, "../figures/processmaps/pn_alpha_complete.png") + +is_sound = pm4py.check_soundness(a_net, im, fm) +is_sound[0] + +len(a_net.arcs) +len(a_net.transitions) +len(a_net.places) + +## Inductive Miner +i_net, im, fm = pm4py.discover_petri_net_inductive(event_log) +i_eval = eval_pm(event_log, i_net, im, fm) +pm4py.vis.view_petri_net(i_net, im, fm) +pm4py.vis.save_vis_petri_net(i_net, im, fm, "../figures/processmaps/pn_induction_complete.png") + +# as process tree (does not work for heuristics miner!) +pt = pm4py.discover_process_tree_inductive(event_log) +pm4py.vis.view_process_tree(pt) + +is_sound = pm4py.check_soundness(i_net, im, fm) +is_sound[0] + +# TODO: Can I show that this simpler net does not include all traces? (Probably not, +# since fitness is 1, but WHY?) + +len(i_net.arcs) +len(i_net.transitions) +len(i_net.places) + +bpmn = pm4py.convert.convert_to_bpmn(i_net, im, fm) +pm4py.view_bpmn(bpmn) + +from pm4py.algo.conformance.tokenreplay import algorithm as token_based_replay +parameters_tbr = {token_based_replay.Variants.TOKEN_REPLAY.value.Parameters.DISABLE_VARIANTS: True, token_based_replay.Variants.TOKEN_REPLAY.value.Parameters.ENABLE_PLTR_FITNESS: True} +replayed_traces, place_fitness, trans_fitness, unwanted_activities = token_based_replay.apply(event_log, i_net, + im, + fm, + parameters=parameters_tbr) + +l1 = list() +l2 = list() +l3 = list() +l4 = list() +for i in range(len(replayed_traces)): + l1.append(replayed_traces[i]["remaining_tokens"]) + l2.append(replayed_traces[i]["missing_tokens"]) + l3.append(replayed_traces[i]["reached_marking"]) + l4.append(replayed_traces[i]["transitions_with_problems"]) + +np.mean(l1) +np.mean(l2) +set(l3) +l4.count([]) + +## ILP Miner +ilp_net, im, fm = pm4py.discover_petri_net_ilp(event_log) +ilp_eval = eval_pm(event_log, ilp_net, im, fm) +pm4py.vis.view_petri_net(ilp_net, im, fm) +pm4py.vis.save_vis_petri_net(ilp_net, im, fm, "../figures/processmaps/pn_ilp_complete.png") + +is_sound = pm4py.check_soundness(ilp_net, im, fm) +is_sound[0] + +len(ilp_net.arcs) +len(ilp_net.transitions) +len(ilp_net.places) + +## Export for all miners +eval = pd.DataFrame(np.row_stack([baseline_eval, h_eval, a_eval, i_eval, ilp_eval])) +eval.columns = ["fitness", "precision", "generalizability", "simplicity"] +eval.index = ["conformative", "heuristics", "alpha", "inductive", "ilp"] +eval + +eval.to_csv("results/eval_all-miners_complete.csv", sep=";") + +###### Process Mining - individual artworks ###### + +def pm_artworks(miner): + + retval1 = np.empty((len(event_log["case:artwork"].unique()), 4)) + retval2 = np.empty((len(event_log["case:artwork"].unique()), 4)) + + if miner == "heuristics": + net, im, fm = pm4py.discover_petri_net_heuristics(event_log) + elif miner == "inductive": + net, im, fm = pm4py.discover_petri_net_inductive(event_log) + elif miner == "alpha": + net, im, fm = pm4py.discover_petri_net_alpha(event_log) + elif miner == "ilp": + net, im, fm = pm4py.discover_petri_net_ilp(event_log) + + for i in range(len(event_log["case:artwork"].unique())): + artwork = event_log["case:artwork"].unique()[i] + subdata = pm4py.filter_event_attribute_values(event_log, "case:artwork", + [artwork], + level="case", retain=True) + if miner == "heuristics": + subnet, subim, subfm = pm4py.discover_petri_net_heuristics(subdata) + elif miner == "inductive": + subnet, subim, subfm = pm4py.discover_petri_net_inductive(subdata) + elif miner == "alpha": + subnet, subim, subfm = pm4py.discover_petri_net_alpha(subdata) + elif miner == "ilp": + subnet, subim, subfm = pm4py.discover_petri_net_ilp(subdata) + #pm4py.save_vis_petri_net(subnet, subim, subfm, + # "../figures/processmaps/artworks/petrinet_" + miner + "_" + str(artwork).zfill(3) + ".png") + retval1[i] = eval_pm(subdata, net, im, fm) + retval2[i] = eval_pm(subdata, subnet, subim, subfm) + + retval1 = pd.DataFrame(retval1) + retval1.columns = ["fitness", "precision", "generalizability", "simplicity"] + retval1.index = event_log["case:artwork"].unique() + retval1.insert(0, "nettype", "alldata") + retval2 = pd.DataFrame(retval2) + retval2.columns = ["fitness", "precision", "generalizability", "simplicity"] + retval2.index = event_log["case:artwork"].unique() + retval2.insert(0, "nettype", "subdata") + return pd.concat([retval1, retval2]) + + +for miner in ["heuristics", "inductive", "alpha", "ilp"]: + eval_art = pm_artworks(miner = miner) + eval_art.to_csv("results/eval_artworks_" + miner + ".csv", sep=";") + +eval_art = pm_artworks(miner = "inductive") + +##### Clustering ###### + +## KMeans + +#eval_artworks = eval_art[eval_art.nettype == "alldata"].iloc[:,range(1,5)] +eval_artworks = eval_art[eval_art.nettype == "subdata"].iloc[:,range(1,5)] + +kmeans = KMeans(n_clusters=4, max_iter=1000).fit(eval_artworks) + +#from sklearn.manifold import MDS +#coord = pd.DataFrame(MDS(normalized_stress='auto').fit_transform(eval_artworks)) + +coord = eval_artworks +coord["clusters"] = kmeans.labels_ + +for i in coord.clusters.unique(): + #plt.scatter(coord[coord.clusters == i].iloc[:,0], coord[coord.clusters == i].iloc[:,1], + plt.scatter(coord[coord.clusters == i].iloc[:,1], coord[coord.clusters == i].iloc[:,2], + #plt.scatter(coord[coord.clusters == i].iloc[:,2], coord[coord.clusters == i].iloc[:,4], + label = i) +plt.legend() +plt.show() + +### Scree plot + +sse = {} +for k in range(1, 10): + kmeans = KMeans(n_clusters=k, max_iter=1000).fit(eval_artworks[["precision", "generalizability"]]) + #data["clusters"] = kmeans.labels_ + #print(data["clusters"]) + sse[k] = kmeans.inertia_ # Inertia: Sum of distances of samples to their closest cluster center +plt.figure() +plt.plot(list(sse.keys()), list(sse.values())) +plt.xlabel("Number of clusters") +plt.ylabel("SSE") +plt.show() + diff --git a/code/create-petrinet.py b/code/create-petrinet.py new file mode 100644 index 0000000..bccf41e --- /dev/null +++ b/code/create-petrinet.py @@ -0,0 +1,251 @@ +import pm4py +from pm4py.objects.petri_net.obj import PetriNet, Marking +from pm4py.objects.petri_net.utils import petri_utils + +# Create places +source = PetriNet.Place("source") +sink = PetriNet.Place("sink") +p_1 = PetriNet.Place("p_1") +p_2 = PetriNet.Place("p_2") +p_3 = PetriNet.Place("p_3") +p_4 = PetriNet.Place("p_4") +p_5 = PetriNet.Place("p_5") +p_6 = PetriNet.Place("p_6") +p_7 = PetriNet.Place("p_7") +p_8 = PetriNet.Place("p_8") +p_9 = PetriNet.Place("p_9") +p_10 = PetriNet.Place("p_10") +p_11 = PetriNet.Place("p_11") +p_12 = PetriNet.Place("p_12") + +# Create transitions +mv = PetriNet.Transition("mv", "move") +fc = PetriNet.Transition("fc", "flipCard") +ot = PetriNet.Transition("ot", "openTopic") +op = PetriNet.Transition("op", "openPopup") + +# Create hidden transitions +t_1 = PetriNet.Transition("t_1") +t_2 = PetriNet.Transition("t_2") +t_3 = PetriNet.Transition("t_3") +t_4 = PetriNet.Transition("t_4") +t_5 = PetriNet.Transition("t_5") +t_6 = PetriNet.Transition("t_6") +t_7 = PetriNet.Transition("t_7") +t_8 = PetriNet.Transition("t_8") +t_9 = PetriNet.Transition("t_9") +t_10 = PetriNet.Transition("t_10") +t_11 = PetriNet.Transition("t_11") +t_12 = PetriNet.Transition("t_12") +t_13 = PetriNet.Transition("t_13") +t_14 = PetriNet.Transition("t_14") +t_15 = PetriNet.Transition("t_15") +t_16 = PetriNet.Transition("t_16") +t_17 = PetriNet.Transition("t_17") +t_18 = PetriNet.Transition("t_18") + +## Sequential net +net_seq = PetriNet("new_petri_net") + +# Add places +net_seq.places.add(source) +net_seq.places.add(sink) +net_seq.places.add(p_1) +net_seq.places.add(p_2) +net_seq.places.add(p_3) +net_seq.places.add(p_4) +net_seq.places.add(p_5) +net_seq.places.add(p_6) +net_seq.places.add(p_7) +net_seq.places.add(p_8) + +# Add transitions +net_seq.transitions.add(mv) +net_seq.transitions.add(fc) +net_seq.transitions.add(ot) +net_seq.transitions.add(op) + +# Add hidden transitions +net_seq.transitions.add(t_1) +net_seq.transitions.add(t_2) +net_seq.transitions.add(t_3) +net_seq.transitions.add(t_4) +net_seq.transitions.add(t_5) +net_seq.transitions.add(t_6) +net_seq.transitions.add(t_7) +net_seq.transitions.add(t_8) +net_seq.transitions.add(t_9) +net_seq.transitions.add(t_10) +net_seq.transitions.add(t_11) +net_seq.transitions.add(t_12) +net_seq.transitions.add(t_13) +net_seq.transitions.add(t_14) +net_seq.transitions.add(t_15) +net_seq.transitions.add(t_16) +net_seq.transitions.add(t_17) +net_seq.transitions.add(t_18) + +# Add arcs +petri_utils.add_arc_from_to(source, t_1, net_seq) +petri_utils.add_arc_from_to(source, t_2, net_seq) +petri_utils.add_arc_from_to(t_1, p_1, net_seq) +petri_utils.add_arc_from_to(t_2, p_2, net_seq) +petri_utils.add_arc_from_to(p_1, mv, net_seq) +petri_utils.add_arc_from_to(p_2, fc, net_seq) +petri_utils.add_arc_from_to(mv, p_3, net_seq) +petri_utils.add_arc_from_to(p_3, t_3, net_seq) +petri_utils.add_arc_from_to(p_3, t_4, net_seq) +petri_utils.add_arc_from_to(p_3, t_5, net_seq) +petri_utils.add_arc_from_to(p_3, t_6, net_seq) +petri_utils.add_arc_from_to(p_3, t_7, net_seq) +petri_utils.add_arc_from_to(t_7, p_1, net_seq) +petri_utils.add_arc_from_to(fc, p_4, net_seq) +petri_utils.add_arc_from_to(p_4, t_8, net_seq) +petri_utils.add_arc_from_to(p_4, t_9, net_seq) +petri_utils.add_arc_from_to(p_4, t_10, net_seq) +petri_utils.add_arc_from_to(t_9, p_1, net_seq) +petri_utils.add_arc_from_to(t_16, p_5, net_seq) +petri_utils.add_arc_from_to(t_3, p_2, net_seq) +petri_utils.add_arc_from_to(t_5, p_6, net_seq) +petri_utils.add_arc_from_to(t_6, p_5, net_seq) +petri_utils.add_arc_from_to(p_6, ot, net_seq) +petri_utils.add_arc_from_to(p_5, op, net_seq) +petri_utils.add_arc_from_to(ot, p_8, net_seq) +petri_utils.add_arc_from_to(op, p_7, net_seq) +petri_utils.add_arc_from_to(p_8, t_11, net_seq) +petri_utils.add_arc_from_to(p_8, t_12, net_seq) +petri_utils.add_arc_from_to(p_8, t_13, net_seq) +petri_utils.add_arc_from_to(p_8, t_17, net_seq) +petri_utils.add_arc_from_to(t_10, p_6, net_seq) +petri_utils.add_arc_from_to(t_17, p_6, net_seq) +petri_utils.add_arc_from_to(p_7, t_14, net_seq) +petri_utils.add_arc_from_to(p_7, t_15, net_seq) +petri_utils.add_arc_from_to(p_7, t_16, net_seq) +petri_utils.add_arc_from_to(p_7, t_18, net_seq) +petri_utils.add_arc_from_to(t_18, p_6, net_seq) +petri_utils.add_arc_from_to(t_13, p_5, net_seq) +petri_utils.add_arc_from_to(t_15, p_1, net_seq) +petri_utils.add_arc_from_to(t_11, p_1, net_seq) +petri_utils.add_arc_from_to(t_4, sink, net_seq) +petri_utils.add_arc_from_to(t_8, sink, net_seq) +petri_utils.add_arc_from_to(t_12, sink, net_seq) +petri_utils.add_arc_from_to(t_14, sink, net_seq) + +# Add tokens +initial_marking = Marking() +initial_marking[source] = 1 +final_marking = Marking() +final_marking[sink] = 1 + +pm4py.view_petri_net(net_seq, initial_marking, final_marking) +pm4py.write_pnml(net_seq, initial_marking, final_marking, "results/conformative_petrinet_seq.pnml") + +pm4py.vis.save_vis_petri_net(net_seq, initial_marking, final_marking, + "../figures/conformative_petrinet_seq.png") + +bpmn = pm4py.convert.convert_to_bpmn(net_seq, initial_marking, final_marking) +pm4py.view_bpmn(bpmn) + +pm4py.vis.save_vis_bpmn(bpmn, "../figures/conformative_bpmn_seq.png") + + +## Concurrent net +net_con = PetriNet("new_petri_net") + +# Add places +net_con.places.add(source) +net_con.places.add(sink) +net_con.places.add(p_1) +net_con.places.add(p_2) +net_con.places.add(p_3) +net_con.places.add(p_4) +net_con.places.add(p_5) +net_con.places.add(p_6) +net_con.places.add(p_7) +net_con.places.add(p_8) +net_con.places.add(p_9) +net_con.places.add(p_10) +net_con.places.add(p_11) +net_con.places.add(p_12) + +# Add transitions +net_con.transitions.add(mv) +net_con.transitions.add(fc) +net_con.transitions.add(ot) +net_con.transitions.add(op) + +# Add hidden transitions +net_con.transitions.add(t_1) +net_con.transitions.add(t_2) +net_con.transitions.add(t_3) +net_con.transitions.add(t_4) +net_con.transitions.add(t_5) +net_con.transitions.add(t_6) +net_con.transitions.add(t_7) +net_con.transitions.add(t_8) +net_con.transitions.add(t_9) +net_con.transitions.add(t_10) +net_con.transitions.add(t_11) +net_con.transitions.add(t_12) +net_con.transitions.add(t_13) +net_con.transitions.add(t_14) +net_con.transitions.add(t_15) + +# Add arcs +petri_utils.add_arc_from_to(source, t_1, net_con) +petri_utils.add_arc_from_to(t_1, p_1, net_con) +petri_utils.add_arc_from_to(t_1, p_2, net_con) +petri_utils.add_arc_from_to(p_1, t_2, net_con) +petri_utils.add_arc_from_to(p_1, t_3, net_con) +petri_utils.add_arc_from_to(t_3, p_5, net_con) +petri_utils.add_arc_from_to(t_2, p_3, net_con) +petri_utils.add_arc_from_to(p_3, mv, net_con) +petri_utils.add_arc_from_to(mv, p_4, net_con) +petri_utils.add_arc_from_to(p_4, t_5, net_con) +petri_utils.add_arc_from_to(p_4, t_6, net_con) +petri_utils.add_arc_from_to(t_6, p_3, net_con) +petri_utils.add_arc_from_to(t_5, p_5, net_con) +petri_utils.add_arc_from_to(p_5, t_15, net_con) +petri_utils.add_arc_from_to(t_15, sink, net_con) +petri_utils.add_arc_from_to(p_2, fc, net_con) +petri_utils.add_arc_from_to(p_2, t_8, net_con) +petri_utils.add_arc_from_to(t_8, p_12, net_con) +petri_utils.add_arc_from_to(p_12, t_15, net_con) +petri_utils.add_arc_from_to(fc, p_6, net_con) +petri_utils.add_arc_from_to(p_6, t_9, net_con) +petri_utils.add_arc_from_to(t_9, p_12, net_con) +petri_utils.add_arc_from_to(p_6, t_4, net_con) +petri_utils.add_arc_from_to(t_4, p_7, net_con) +petri_utils.add_arc_from_to(p_7, ot, net_con) +petri_utils.add_arc_from_to(ot, p_8, net_con) +petri_utils.add_arc_from_to(p_8, t_10, net_con) +petri_utils.add_arc_from_to(t_10, p_11, net_con) +petri_utils.add_arc_from_to(p_11, t_13, net_con) +petri_utils.add_arc_from_to(t_13, p_12, net_con) +petri_utils.add_arc_from_to(p_8, t_7, net_con) +petri_utils.add_arc_from_to(t_7, p_9, net_con) +petri_utils.add_arc_from_to(p_9, op, net_con) +petri_utils.add_arc_from_to(op, p_10, net_con) +petri_utils.add_arc_from_to(p_10, t_11, net_con) +petri_utils.add_arc_from_to(p_10, t_12, net_con) +petri_utils.add_arc_from_to(t_12, p_9, net_con) +petri_utils.add_arc_from_to(t_11, p_11, net_con) +petri_utils.add_arc_from_to(p_11, t_14, net_con) +petri_utils.add_arc_from_to(t_14, p_7, net_con) + +# Add tokens +initial_marking = Marking() +initial_marking[source] = 1 +final_marking = Marking() +final_marking[sink] = 1 + +pm4py.view_petri_net(net_con, initial_marking, final_marking) +pm4py.write_pnml(net_con, initial_marking, final_marking, "results/conformative_petrinet_con.pnml") + +pm4py.vis.save_vis_petri_net(net_con, initial_marking, final_marking, + "../figures/conformative_petrinet_con.png") + +bpmn = pm4py.convert.convert_to_bpmn(net_con, initial_marking, final_marking) +pm4py.view_bpmn(bpmn) + +pm4py.vis.save_vis_bpmn(bpmn, "../figures/conformative_bpmn_con.png") diff --git a/code/create_petrinet.py b/code/create_petrinet.py deleted file mode 100644 index 625a2c5..0000000 --- a/code/create_petrinet.py +++ /dev/null @@ -1,144 +0,0 @@ -import pm4py -from pm4py.objects.petri_net.obj import PetriNet, Marking -from pm4py.objects.petri_net.utils import petri_utils - -net = PetriNet("new_petri_net") - -# creating source, p_1 and sink place -source = PetriNet.Place("source") -sink = PetriNet.Place("sink") -p_1 = PetriNet.Place("p_1") -p_2 = PetriNet.Place("p_2") -p_3 = PetriNet.Place("p_3") -p_4 = PetriNet.Place("p_4") -p_5 = PetriNet.Place("p_5") -p_6 = PetriNet.Place("p_6") -p_7 = PetriNet.Place("p_7") -p_8 = PetriNet.Place("p_8") - -# add the places to the Petri Net -net.places.add(source) -net.places.add(sink) -net.places.add(p_1) -net.places.add(p_2) -net.places.add(p_3) -net.places.add(p_4) -net.places.add(p_5) -net.places.add(p_6) -net.places.add(p_7) -net.places.add(p_8) - -# Create transitions -mv = PetriNet.Transition("mv", "move") -fc = PetriNet.Transition("fc", "flipCard") -ot = PetriNet.Transition("ot", "openTopic") -op = PetriNet.Transition("op", "openPopup") -## hidden transitions -t_1 = PetriNet.Transition("t_1") -t_2 = PetriNet.Transition("t_2") -t_3 = PetriNet.Transition("t_3") -t_4 = PetriNet.Transition("t_4") -t_5 = PetriNet.Transition("t_5") -t_6 = PetriNet.Transition("t_6") -t_7 = PetriNet.Transition("t_7") -t_8 = PetriNet.Transition("t_8") -t_9 = PetriNet.Transition("t_9") -t_10 = PetriNet.Transition("t_10") -t_11 = PetriNet.Transition("t_11") -t_12 = PetriNet.Transition("t_12") -t_13 = PetriNet.Transition("t_13") -t_14 = PetriNet.Transition("t_14") -t_15 = PetriNet.Transition("t_15") -t_16 = PetriNet.Transition("t_16") - -# Add the transitions to the Petri Net -net.transitions.add(mv) -net.transitions.add(fc) -net.transitions.add(ot) -net.transitions.add(op) - -# add hidden transitions -net.transitions.add(t_1) -net.transitions.add(t_2) -net.transitions.add(t_3) -net.transitions.add(t_4) -net.transitions.add(t_5) -net.transitions.add(t_6) -net.transitions.add(t_7) -net.transitions.add(t_8) -net.transitions.add(t_9) -net.transitions.add(t_10) -net.transitions.add(t_11) -net.transitions.add(t_12) -net.transitions.add(t_13) -net.transitions.add(t_14) -net.transitions.add(t_15) -net.transitions.add(t_16) - -# Add arcs -petri_utils.add_arc_from_to(source, t_1, net) -petri_utils.add_arc_from_to(source, t_2, net) -petri_utils.add_arc_from_to(t_1, p_1, net) -petri_utils.add_arc_from_to(t_2, p_2, net) -petri_utils.add_arc_from_to(p_1, mv, net) -petri_utils.add_arc_from_to(p_2, fc, net) -petri_utils.add_arc_from_to(mv, p_3, net) -petri_utils.add_arc_from_to(p_3, t_3, net) -petri_utils.add_arc_from_to(p_3, t_4, net) -petri_utils.add_arc_from_to(p_3, t_5, net) -petri_utils.add_arc_from_to(p_3, t_6, net) -petri_utils.add_arc_from_to(p_3, t_7, net) -petri_utils.add_arc_from_to(t_7, p_1, net) - -petri_utils.add_arc_from_to(fc, p_4, net) -petri_utils.add_arc_from_to(p_4, t_8, net) -petri_utils.add_arc_from_to(p_4, t_9, net) -petri_utils.add_arc_from_to(p_4, t_10, net) -petri_utils.add_arc_from_to(t_9, p_1, net) -petri_utils.add_arc_from_to(p_7, t_16, net) -petri_utils.add_arc_from_to(t_16, p_6, net) - -petri_utils.add_arc_from_to(t_3, p_2, net) -petri_utils.add_arc_from_to(t_5, p_6, net) -petri_utils.add_arc_from_to(t_6, p_5, net) - -petri_utils.add_arc_from_to(p_6, ot, net) -petri_utils.add_arc_from_to(p_5, op, net) - -petri_utils.add_arc_from_to(ot, p_8, net) -petri_utils.add_arc_from_to(op, p_7, net) - -petri_utils.add_arc_from_to(p_8, t_10, net) -petri_utils.add_arc_from_to(p_8, t_11, net) -petri_utils.add_arc_from_to(p_8, t_12, net) -petri_utils.add_arc_from_to(p_8, t_13, net) -petri_utils.add_arc_from_to(t_10, p_6, net) - -petri_utils.add_arc_from_to(p_7, t_13, net) -petri_utils.add_arc_from_to(p_7, t_14, net) -petri_utils.add_arc_from_to(p_7, t_15, net) -petri_utils.add_arc_from_to(t_13, p_5, net) -petri_utils.add_arc_from_to(t_15, p_1, net) -petri_utils.add_arc_from_to(t_11, p_1, net) - -petri_utils.add_arc_from_to(t_4, sink, net) -petri_utils.add_arc_from_to(t_8, sink, net) -petri_utils.add_arc_from_to(t_12, sink, net) -petri_utils.add_arc_from_to(t_14, sink, net) - - -# Adding tokens -initial_marking = Marking() -initial_marking[source] = 1 -final_marking = Marking() -final_marking[sink] = 1 - -pm4py.view_petri_net(net, initial_marking, final_marking) -pm4py.write_pnml(net, initial_marking, final_marking, "results/normative_petrinet.pnml") - -pm4py.vis.save_vis_petri_net(net, initial_marking, final_marking, "../figures/normative_petrinet.png") - -bpmn = pm4py.convert.convert_to_bpmn(net, initial_marking, final_marking) -pm4py.view_bpmn(bpmn) - -pm4py.vis.save_vis_bpmn(bpmn, "../figures/normative_bpmn.png") diff --git a/code/plots_petri-nets.py b/code/plots_petri-nets.py new file mode 100644 index 0000000..4d467a1 --- /dev/null +++ b/code/plots_petri-nets.py @@ -0,0 +1,114 @@ +%reset + +import pm4py +from pm4py.objects.petri_net.obj import PetriNet, Marking + +net_con, initial_marking, final_marking = pm4py.read_pnml("results/conformative_petrinet_con.pnml") +pm4py.view_petri_net(net_con, initial_marking, final_marking) + +net_con.places +net_con.transitions +net_con.arcs + +help(pm4py.objects.petri_net.obj.Marking) + +# Places +source = PetriNet.Place("source") +sink = PetriNet.Place("sink") +p_1 = PetriNet.Place("p_1") +p_2 = PetriNet.Place("p_2") +p_3 = PetriNet.Place("p_3") +p_4 = PetriNet.Place("p_4") +p_5 = PetriNet.Place("p_5") +p_6 = PetriNet.Place("p_6") +p_7 = PetriNet.Place("p_7") +p_8 = PetriNet.Place("p_8") +p_9 = PetriNet.Place("p_9") +p_10 = PetriNet.Place("p_10") +p_11 = PetriNet.Place("p_11") +p_12 = PetriNet.Place("p_12") + + +# Add tokens for traces +# ('flipCard', 'openTopic', 'openPopup', 'openTopic', 'move'): 14 +#pm4py.view_petri_net(net_con, initial_marking) +pm4py.vis.save_vis_petri_net(net_con, initial_marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_01.png") +marking = pm4py.generate_marking(net_con, {'p_1': 1, 'p_2' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_02.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_1': 1, 'p_6' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_03.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_1': 1, 'p_7' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_04.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_1': 1, 'p_8' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_05.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_1': 1, 'p_9' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_06.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_1': 1, 'p_10' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_07.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_1': 1, 'p_11' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_08.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_1': 1, 'p_7' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_09.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_1': 1, 'p_8' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_10.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_3': 1, 'p_8' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_11.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_4': 1, 'p_8' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_12.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_5': 1, 'p_8' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_13.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_5': 1, 'p_11' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_14.png") +#pm4py.view_petri_net(net_con, marking) +marking = pm4py.generate_marking(net_con, {'p_5': 1, 'p_12' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_15.png") +#pm4py.view_petri_net(net_con, marking) +pm4py.vis.save_vis_petri_net(net_con, final_marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_1_16.png") +#pm4py.view_petri_net(net_con, final_marking) + +# ('move', 'move', 'flipCard', 'move', 'openTopic', 'openPopup'): 14 +pm4py.vis.save_vis_petri_net(net_con, initial_marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_01.png") +marking = pm4py.generate_marking(net_con, {'p_1': 1, 'p_2' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_02.png") +marking = pm4py.generate_marking(net_con, {'p_3': 1, 'p_2' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_03.png") +marking = pm4py.generate_marking(net_con, {'p_4': 1, 'p_2' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_04.png") +marking = pm4py.generate_marking(net_con, {'p_3': 1, 'p_2' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_05.png") +marking = pm4py.generate_marking(net_con, {'p_4': 1, 'p_2' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_06.png") +marking = pm4py.generate_marking(net_con, {'p_4': 1, 'p_6' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_07.png") +marking = pm4py.generate_marking(net_con, {'p_3': 1, 'p_6' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_08.png") +marking = pm4py.generate_marking(net_con, {'p_4': 1, 'p_6' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_09.png") +marking = pm4py.generate_marking(net_con, {'p_4': 1, 'p_7' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_10.png") +marking = pm4py.generate_marking(net_con, {'p_4': 1, 'p_8' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_11.png") +marking = pm4py.generate_marking(net_con, {'p_4': 1, 'p_9' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_12.png") +marking = pm4py.generate_marking(net_con, {'p_4': 1, 'p_10' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_13.png") +marking = pm4py.generate_marking(net_con, {'p_4': 1, 'p_11' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_14.png") +marking = pm4py.generate_marking(net_con, {'p_4': 1, 'p_12' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_15.png") +marking = pm4py.generate_marking(net_con, {'p_5': 1, 'p_12' : 1}) +pm4py.vis.save_vis_petri_net(net_con, marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_16.png") +pm4py.vis.save_vis_petri_net(net_con, final_marking, final_marking, file_path="../figures/processmaps/conformative_net_con_markings_2_17.png") +