openprocess 0.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cpnpy/__init__.py +46 -0
- openprocess/__init__.py +57 -0
- openprocess/analysis/__init__.py +0 -0
- openprocess/analysis/state_space.py +521 -0
- openprocess/analysis/state_space_process.py +251 -0
- openprocess/cli.py +742 -0
- openprocess/exercises/1 Petri nets/Exercise 1.1 Order handling/answer.pnml +31 -0
- openprocess/exercises/1 Petri nets/Exercise 1.1 Order handling/question.md +38 -0
- openprocess/exercises/2 Soundness/Exercise 2.1 Spot the flaw/answer.pnml +27 -0
- openprocess/exercises/2 Soundness/Exercise 2.1 Spot the flaw/net.pnml +29 -0
- openprocess/exercises/2 Soundness/Exercise 2.1 Spot the flaw/question.md +65 -0
- openprocess/exercises/3 Discovery/Exercise 3.1 The alpha-algorithm/log.txt +1 -0
- openprocess/exercises/3 Discovery/Exercise 3.1 The alpha-algorithm/question.md +67 -0
- openprocess/exercises/4 Regions/Exercise 4.1 Regions of a transition system/question.md +75 -0
- openprocess/exercises/4 Regions/Exercise 4.1 Regions of a transition system/ts.txt +5 -0
- openprocess/exercises/5 Markings/Exercise 5.1 Markings and matrices/net.pnml +27 -0
- openprocess/exercises/5 Markings/Exercise 5.1 Markings and matrices/question.md +65 -0
- openprocess/exercises/6 Inductive Miner/Exercise 6.1 Cuts and trees/log.txt +1 -0
- openprocess/exercises/6 Inductive Miner/Exercise 6.1 Cuts and trees/question.md +62 -0
- openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/log.txt +1 -0
- openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/m1.pnml +36 -0
- openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/m2.pnml +28 -0
- openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/m3.pnml +30 -0
- openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/net.pnml +36 -0
- openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/question.md +69 -0
- openprocess/exercises/pack.md +14 -0
- openprocess/flow/__init__.py +50 -0
- openprocess/flow/box.py +466 -0
- openprocess/flow/boxes/__init__.py +7 -0
- openprocess/flow/boxes/check.py +119 -0
- openprocess/flow/boxes/compare.py +16 -0
- openprocess/flow/boxes/cpn.py +53 -0
- openprocess/flow/boxes/discover.py +124 -0
- openprocess/flow/boxes/filter.py +80 -0
- openprocess/flow/boxes/input.py +124 -0
- openprocess/flow/boxes/output.py +52 -0
- openprocess/flow/boxes/predict.py +186 -0
- openprocess/flow/boxes/science.py +159 -0
- openprocess/flow/boxes/sweeps.py +18 -0
- openprocess/flow/convert.py +187 -0
- openprocess/flow/datasets.py +198 -0
- openprocess/flow/explain.py +115 -0
- openprocess/flow/library.py +222 -0
- openprocess/flow/record.py +385 -0
- openprocess/flow/runner.py +357 -0
- openprocess/flow/sweep.py +92 -0
- openprocess/flow/types.py +290 -0
- openprocess/flow/workflow.py +628 -0
- openprocess/gui/__init__.py +0 -0
- openprocess/gui/app.py +90 -0
- openprocess/gui/arc_editing.py +295 -0
- openprocess/gui/canvas.py +1414 -0
- openprocess/gui/flow/__init__.py +8 -0
- openprocess/gui/flow/canvas.py +854 -0
- openprocess/gui/flow/page.py +972 -0
- openprocess/gui/flow/templates.py +131 -0
- openprocess/gui/flow/viewers.py +665 -0
- openprocess/gui/items.py +1275 -0
- openprocess/gui/learn/answer_boxes.py +978 -0
- openprocess/gui/learn/concealment.py +91 -0
- openprocess/gui/learn/mode.py +1181 -0
- openprocess/gui/panning.py +241 -0
- openprocess/gui/resources/openprocess-icon.png +0 -0
- openprocess/gui/studio/__init__.py +1 -0
- openprocess/gui/studio/__main__.py +3 -0
- openprocess/gui/studio/app.py +4031 -0
- openprocess/gui/studio/charts.py +115 -0
- openprocess/gui/studio/compare_page.py +487 -0
- openprocess/gui/studio/cpn_page.py +1858 -0
- openprocess/gui/studio/definition_view.py +284 -0
- openprocess/gui/studio/derivation_view.py +421 -0
- openprocess/gui/studio/documents.py +152 -0
- openprocess/gui/studio/dotted_chart.py +1401 -0
- openprocess/gui/studio/file_dialogs.py +143 -0
- openprocess/gui/studio/filter_dialog.py +247 -0
- openprocess/gui/studio/graph_builders.py +176 -0
- openprocess/gui/studio/graph_view.py +682 -0
- openprocess/gui/studio/instances.py +413 -0
- openprocess/gui/studio/log_editor.py +675 -0
- openprocess/gui/studio/log_page.py +800 -0
- openprocess/gui/studio/markdown_view.py +127 -0
- openprocess/gui/studio/mathtext.py +260 -0
- openprocess/gui/studio/ml_highlighter.py +75 -0
- openprocess/gui/studio/model_page.py +760 -0
- openprocess/gui/studio/net_comparison.py +124 -0
- openprocess/gui/studio/notes_overlay.py +275 -0
- openprocess/gui/studio/petri_page.py +844 -0
- openprocess/gui/studio/regions_view.py +502 -0
- openprocess/gui/studio/sidebar.py +149 -0
- openprocess/gui/studio/style.py +503 -0
- openprocess/gui/studio/tool_icons.py +134 -0
- openprocess/gui/studio/updates.py +439 -0
- openprocess/gui/studio/widgets.py +899 -0
- openprocess/gui/studio/workers.py +60 -0
- openprocess/gui/studio/workspace.py +447 -0
- openprocess/gui/theme.py +394 -0
- openprocess/gui/tidy.py +86 -0
- openprocess/io/__init__.py +0 -0
- openprocess/io/cpn_reader.py +389 -0
- openprocess/io/cpn_writer.py +357 -0
- openprocess/learn/__init__.py +23 -0
- openprocess/learn/answers.py +188 -0
- openprocess/learn/checks.py +953 -0
- openprocess/learn/computed.py +1180 -0
- openprocess/learn/context.py +145 -0
- openprocess/learn/exam.py +169 -0
- openprocess/learn/exercise-packs.md +325 -0
- openprocess/learn/importer.py +216 -0
- openprocess/learn/notation.py +474 -0
- openprocess/learn/pack.py +511 -0
- openprocess/learn/sheet.py +296 -0
- openprocess/mining/__init__.py +73 -0
- openprocess/mining/analysis.py +689 -0
- openprocess/mining/columns.py +282 -0
- openprocess/mining/compare_nets.py +246 -0
- openprocess/mining/conformance/__init__.py +0 -0
- openprocess/mining/conformance/alignments.py +263 -0
- openprocess/mining/conformance/quality.py +145 -0
- openprocess/mining/conformance/token_replay.py +252 -0
- openprocess/mining/csv_import.py +222 -0
- openprocess/mining/definitions.py +584 -0
- openprocess/mining/dfg.py +187 -0
- openprocess/mining/discovery/__init__.py +0 -0
- openprocess/mining/discovery/alpha.py +168 -0
- openprocess/mining/discovery/heuristics.py +332 -0
- openprocess/mining/discovery/inductive.py +477 -0
- openprocess/mining/discovery/state_regions.py +62 -0
- openprocess/mining/filtering.py +237 -0
- openprocess/mining/footprint.py +183 -0
- openprocess/mining/invariants.py +191 -0
- openprocess/mining/layout.py +279 -0
- openprocess/mining/log.py +364 -0
- openprocess/mining/petrinet.py +354 -0
- openprocess/mining/playout.py +75 -0
- openprocess/mining/pm4py_bridge.py +82 -0
- openprocess/mining/pnml.py +223 -0
- openprocess/mining/processtree.py +216 -0
- openprocess/mining/regions.py +476 -0
- openprocess/mining/stats.py +160 -0
- openprocess/mining/structure.py +374 -0
- openprocess/mining/transition_system.py +409 -0
- openprocess/mining/xes.py +399 -0
- openprocess/ml/__init__.py +0 -0
- openprocess/ml/ast_nodes.py +332 -0
- openprocess/ml/builtins.py +364 -0
- openprocess/ml/colorsets.py +522 -0
- openprocess/ml/errors.py +60 -0
- openprocess/ml/evaluator.py +754 -0
- openprocess/ml/lexer.py +277 -0
- openprocess/ml/multiset.py +417 -0
- openprocess/ml/parser.py +737 -0
- openprocess/ml/values.py +319 -0
- openprocess/model/__init__.py +0 -0
- openprocess/model/declarations.py +617 -0
- openprocess/model/examples.py +98 -0
- openprocess/model/net.py +701 -0
- openprocess/model/plain.py +192 -0
- openprocess/references.py +280 -0
- openprocess/sim/__init__.py +0 -0
- openprocess/sim/binding.py +620 -0
- openprocess/sim/export.py +66 -0
- openprocess/sim/simulator.py +315 -0
- openprocess/teaching/__init__.py +4 -0
- openprocess/teaching/answers.py +4 -0
- openprocess/teaching/checks.py +5 -0
- openprocess/teaching/pack.py +4 -0
- openprocess/teaching/sheet.py +4 -0
- openprocess-0.7.0.dist-info/METADATA +927 -0
- openprocess-0.7.0.dist-info/RECORD +173 -0
- openprocess-0.7.0.dist-info/WHEEL +5 -0
- openprocess-0.7.0.dist-info/entry_points.txt +6 -0
- openprocess-0.7.0.dist-info/licenses/LICENSE +21 -0
- openprocess-0.7.0.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""Ready-made workflows, so a new workflow never opens as an empty canvas.
|
|
2
|
+
|
|
3
|
+
Each template builds a :class:`~openprocess.flow.workflow.Workflow` around a log:
|
|
4
|
+
a file in the folder when there is one, else a log typed in the course
|
|
5
|
+
notation. They are the examples the README describes, and the starting
|
|
6
|
+
points *New Workflow* offers.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from ...flow.library import Library
|
|
14
|
+
from ...flow.workflow import Workflow
|
|
15
|
+
|
|
16
|
+
L1 = "[<a,b,c,d>^3, <a,c,b,d>^2, <a,e,d>]"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _log(wf: Workflow, log_file: str | None, position=(0.0, 190.0)):
|
|
20
|
+
if log_file:
|
|
21
|
+
return wf.add("open_log", {"file": log_file}, position)
|
|
22
|
+
return wf.add("typed_log", {"text": L1}, position)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def discover_and_check(library: Library, log_file: str | None = None) -> Workflow:
|
|
26
|
+
"""Log → Inductive Miner → Check fit: the three-box workflow."""
|
|
27
|
+
wf = Workflow("Discover and check", library)
|
|
28
|
+
log = _log(wf, log_file, (0.0, 120.0))
|
|
29
|
+
model = wf.add("inductive_miner", {"noise": 0.2}, (240.0, 120.0))
|
|
30
|
+
fit = wf.add("check_fit", {}, (480.0, 100.0))
|
|
31
|
+
wf.connect(log, model)
|
|
32
|
+
wf.connect(model, fit, "model")
|
|
33
|
+
wf.connect(log, fit, "log")
|
|
34
|
+
return wf
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def compare_discovery(library: Library, log_file: str | None = None) -> Workflow:
|
|
38
|
+
"""One log, three miners, their fit side by side."""
|
|
39
|
+
wf = Workflow("Compare discovery", library)
|
|
40
|
+
log = _log(wf, log_file)
|
|
41
|
+
filtered = wf.add("top_variants", {"k": 5}, (230.0, 190.0))
|
|
42
|
+
wf.connect(log, filtered)
|
|
43
|
+
miners = [wf.add("alpha_miner", {}, (470.0, 30.0)), wf.add("inductive_miner", {"noise": 0.2}, (470.0, 190.0)),
|
|
44
|
+
wf.add("heuristics_miner", {"dependency": 0.9}, (470.0, 350.0))]
|
|
45
|
+
compare = wf.add("compare", {}, (960.0, 190.0))
|
|
46
|
+
for index, miner in enumerate(miners):
|
|
47
|
+
check = wf.add("check_fit", {}, (720.0, 20.0 + index * 160.0))
|
|
48
|
+
wf.connect(filtered, miner)
|
|
49
|
+
wf.connect(miner, check, "model")
|
|
50
|
+
wf.connect(log, check, "log")
|
|
51
|
+
wf.connect(check, compare)
|
|
52
|
+
return wf
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def fitness_with_confidence(library: Library, log_file: str | None = None) -> Workflow:
|
|
56
|
+
"""Does the α-algorithm really fit this log better than the Heuristics Miner?
|
|
57
|
+
Bootstrap both, test, plot (needs NumPy, SciPy and matplotlib)."""
|
|
58
|
+
wf = Workflow("Fitness with confidence", library)
|
|
59
|
+
log = _log(wf, log_file)
|
|
60
|
+
alpha = wf.add("alpha_miner", {}, (240.0, 50.0))
|
|
61
|
+
heuristics = wf.add("heuristics_miner", {"dependency": 0.9}, (240.0, 330.0))
|
|
62
|
+
describe = wf.add("describe_log", {}, (240.0, 190.0))
|
|
63
|
+
b1 = wf.add("bootstrap_fitness", {"samples": 200, "seed": 0}, (480.0, 30.0))
|
|
64
|
+
b2 = wf.add("bootstrap_fitness", {"samples": 200, "seed": 1}, (480.0, 310.0))
|
|
65
|
+
test = wf.add("compare_samples", {}, (720.0, 150.0))
|
|
66
|
+
plot = wf.add("plot", {}, (720.0, 330.0))
|
|
67
|
+
for miner, boot in ((alpha, b1), (heuristics, b2)):
|
|
68
|
+
wf.connect(log, miner)
|
|
69
|
+
wf.connect(miner, boot, "model")
|
|
70
|
+
wf.connect(log, boot, "log")
|
|
71
|
+
wf.connect(log, describe)
|
|
72
|
+
wf.connect(b1, test, "a")
|
|
73
|
+
wf.connect(b2, test, "b")
|
|
74
|
+
wf.connect(b1, plot, "tables")
|
|
75
|
+
wf.connect(b2, plot, "tables")
|
|
76
|
+
return wf
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def predict_next_activity(library: Library, log_file: str | None = None) -> Workflow:
|
|
80
|
+
"""Prefixes → split by time → a baseline model → predict → evaluate."""
|
|
81
|
+
wf = Workflow("Predict the next activity", library)
|
|
82
|
+
log = _log(wf, log_file, (0.0, 150.0))
|
|
83
|
+
pre = wf.add("prefixes", {}, (240.0, 150.0))
|
|
84
|
+
split = wf.add("split_by_time", {"train_fraction": 0.7}, (480.0, 150.0))
|
|
85
|
+
model = wf.add("frequency_model", {}, (720.0, 40.0))
|
|
86
|
+
predict = wf.add("predict", {}, (960.0, 150.0))
|
|
87
|
+
evaluate = wf.add("evaluate_predictions", {}, (1200.0, 150.0))
|
|
88
|
+
wf.connect(log, pre)
|
|
89
|
+
wf.connect(pre, split)
|
|
90
|
+
wf.connect(split, model, "train", "train")
|
|
91
|
+
wf.connect(split, predict, "dataset", "test")
|
|
92
|
+
wf.connect(model, predict, "model")
|
|
93
|
+
wf.connect(predict, evaluate)
|
|
94
|
+
return wf
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def noise_sweep(library: Library, log_file: str | None = None) -> Workflow:
|
|
98
|
+
"""The Inductive Miner's noise threshold swept from 0 to 0.5, scores stacked."""
|
|
99
|
+
from ...flow.sweep import Sweep
|
|
100
|
+
wf = Workflow("Noise sweep", library)
|
|
101
|
+
log = _log(wf, log_file, (0.0, 120.0))
|
|
102
|
+
model = wf.add("inductive_miner", {"noise": Sweep.parse("0..0.5 step 0.1")}, (240.0, 120.0))
|
|
103
|
+
fit = wf.add("check_fit", {}, (480.0, 100.0))
|
|
104
|
+
table = wf.add("sweep_table", {}, (720.0, 120.0))
|
|
105
|
+
wf.connect(log, model)
|
|
106
|
+
wf.connect(model, fit, "model")
|
|
107
|
+
wf.connect(log, fit, "log")
|
|
108
|
+
wf.connect(fit, table)
|
|
109
|
+
return wf
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
#: (menu text, builder, one line about it)
|
|
113
|
+
TEMPLATES = [
|
|
114
|
+
("Discover and check", discover_and_check, "a log, the Inductive Miner and a fitness check"),
|
|
115
|
+
("Compare discovery", compare_discovery, "three miners on one log, side by side"),
|
|
116
|
+
("Noise sweep", noise_sweep, "one setting swept over a range, the scores stacked"),
|
|
117
|
+
("Fitness with confidence", fitness_with_confidence, "bootstrap intervals, a test and a plot (NumPy, SciPy, matplotlib)"),
|
|
118
|
+
("Predict the next activity", predict_next_activity, "the prediction pipeline with a baseline model"),
|
|
119
|
+
]
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def first_log(folder: str | Path | None) -> str | None:
|
|
123
|
+
"""A log file of the folder to start from, relative to it (None: none)."""
|
|
124
|
+
if folder is None:
|
|
125
|
+
return None
|
|
126
|
+
folder = Path(folder)
|
|
127
|
+
for pattern in ("*.xes", "*.xes.gz", "*.csv", "*log.txt"):
|
|
128
|
+
for path in sorted(folder.glob(pattern)):
|
|
129
|
+
if not path.name.startswith("."):
|
|
130
|
+
return path.name
|
|
131
|
+
return None
|