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.
Files changed (173) hide show
  1. cpnpy/__init__.py +46 -0
  2. openprocess/__init__.py +57 -0
  3. openprocess/analysis/__init__.py +0 -0
  4. openprocess/analysis/state_space.py +521 -0
  5. openprocess/analysis/state_space_process.py +251 -0
  6. openprocess/cli.py +742 -0
  7. openprocess/exercises/1 Petri nets/Exercise 1.1 Order handling/answer.pnml +31 -0
  8. openprocess/exercises/1 Petri nets/Exercise 1.1 Order handling/question.md +38 -0
  9. openprocess/exercises/2 Soundness/Exercise 2.1 Spot the flaw/answer.pnml +27 -0
  10. openprocess/exercises/2 Soundness/Exercise 2.1 Spot the flaw/net.pnml +29 -0
  11. openprocess/exercises/2 Soundness/Exercise 2.1 Spot the flaw/question.md +65 -0
  12. openprocess/exercises/3 Discovery/Exercise 3.1 The alpha-algorithm/log.txt +1 -0
  13. openprocess/exercises/3 Discovery/Exercise 3.1 The alpha-algorithm/question.md +67 -0
  14. openprocess/exercises/4 Regions/Exercise 4.1 Regions of a transition system/question.md +75 -0
  15. openprocess/exercises/4 Regions/Exercise 4.1 Regions of a transition system/ts.txt +5 -0
  16. openprocess/exercises/5 Markings/Exercise 5.1 Markings and matrices/net.pnml +27 -0
  17. openprocess/exercises/5 Markings/Exercise 5.1 Markings and matrices/question.md +65 -0
  18. openprocess/exercises/6 Inductive Miner/Exercise 6.1 Cuts and trees/log.txt +1 -0
  19. openprocess/exercises/6 Inductive Miner/Exercise 6.1 Cuts and trees/question.md +62 -0
  20. openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/log.txt +1 -0
  21. openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/m1.pnml +36 -0
  22. openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/m2.pnml +28 -0
  23. openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/m3.pnml +30 -0
  24. openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/net.pnml +36 -0
  25. openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/question.md +69 -0
  26. openprocess/exercises/pack.md +14 -0
  27. openprocess/flow/__init__.py +50 -0
  28. openprocess/flow/box.py +466 -0
  29. openprocess/flow/boxes/__init__.py +7 -0
  30. openprocess/flow/boxes/check.py +119 -0
  31. openprocess/flow/boxes/compare.py +16 -0
  32. openprocess/flow/boxes/cpn.py +53 -0
  33. openprocess/flow/boxes/discover.py +124 -0
  34. openprocess/flow/boxes/filter.py +80 -0
  35. openprocess/flow/boxes/input.py +124 -0
  36. openprocess/flow/boxes/output.py +52 -0
  37. openprocess/flow/boxes/predict.py +186 -0
  38. openprocess/flow/boxes/science.py +159 -0
  39. openprocess/flow/boxes/sweeps.py +18 -0
  40. openprocess/flow/convert.py +187 -0
  41. openprocess/flow/datasets.py +198 -0
  42. openprocess/flow/explain.py +115 -0
  43. openprocess/flow/library.py +222 -0
  44. openprocess/flow/record.py +385 -0
  45. openprocess/flow/runner.py +357 -0
  46. openprocess/flow/sweep.py +92 -0
  47. openprocess/flow/types.py +290 -0
  48. openprocess/flow/workflow.py +628 -0
  49. openprocess/gui/__init__.py +0 -0
  50. openprocess/gui/app.py +90 -0
  51. openprocess/gui/arc_editing.py +295 -0
  52. openprocess/gui/canvas.py +1414 -0
  53. openprocess/gui/flow/__init__.py +8 -0
  54. openprocess/gui/flow/canvas.py +854 -0
  55. openprocess/gui/flow/page.py +972 -0
  56. openprocess/gui/flow/templates.py +131 -0
  57. openprocess/gui/flow/viewers.py +665 -0
  58. openprocess/gui/items.py +1275 -0
  59. openprocess/gui/learn/answer_boxes.py +978 -0
  60. openprocess/gui/learn/concealment.py +91 -0
  61. openprocess/gui/learn/mode.py +1181 -0
  62. openprocess/gui/panning.py +241 -0
  63. openprocess/gui/resources/openprocess-icon.png +0 -0
  64. openprocess/gui/studio/__init__.py +1 -0
  65. openprocess/gui/studio/__main__.py +3 -0
  66. openprocess/gui/studio/app.py +4031 -0
  67. openprocess/gui/studio/charts.py +115 -0
  68. openprocess/gui/studio/compare_page.py +487 -0
  69. openprocess/gui/studio/cpn_page.py +1858 -0
  70. openprocess/gui/studio/definition_view.py +284 -0
  71. openprocess/gui/studio/derivation_view.py +421 -0
  72. openprocess/gui/studio/documents.py +152 -0
  73. openprocess/gui/studio/dotted_chart.py +1401 -0
  74. openprocess/gui/studio/file_dialogs.py +143 -0
  75. openprocess/gui/studio/filter_dialog.py +247 -0
  76. openprocess/gui/studio/graph_builders.py +176 -0
  77. openprocess/gui/studio/graph_view.py +682 -0
  78. openprocess/gui/studio/instances.py +413 -0
  79. openprocess/gui/studio/log_editor.py +675 -0
  80. openprocess/gui/studio/log_page.py +800 -0
  81. openprocess/gui/studio/markdown_view.py +127 -0
  82. openprocess/gui/studio/mathtext.py +260 -0
  83. openprocess/gui/studio/ml_highlighter.py +75 -0
  84. openprocess/gui/studio/model_page.py +760 -0
  85. openprocess/gui/studio/net_comparison.py +124 -0
  86. openprocess/gui/studio/notes_overlay.py +275 -0
  87. openprocess/gui/studio/petri_page.py +844 -0
  88. openprocess/gui/studio/regions_view.py +502 -0
  89. openprocess/gui/studio/sidebar.py +149 -0
  90. openprocess/gui/studio/style.py +503 -0
  91. openprocess/gui/studio/tool_icons.py +134 -0
  92. openprocess/gui/studio/updates.py +439 -0
  93. openprocess/gui/studio/widgets.py +899 -0
  94. openprocess/gui/studio/workers.py +60 -0
  95. openprocess/gui/studio/workspace.py +447 -0
  96. openprocess/gui/theme.py +394 -0
  97. openprocess/gui/tidy.py +86 -0
  98. openprocess/io/__init__.py +0 -0
  99. openprocess/io/cpn_reader.py +389 -0
  100. openprocess/io/cpn_writer.py +357 -0
  101. openprocess/learn/__init__.py +23 -0
  102. openprocess/learn/answers.py +188 -0
  103. openprocess/learn/checks.py +953 -0
  104. openprocess/learn/computed.py +1180 -0
  105. openprocess/learn/context.py +145 -0
  106. openprocess/learn/exam.py +169 -0
  107. openprocess/learn/exercise-packs.md +325 -0
  108. openprocess/learn/importer.py +216 -0
  109. openprocess/learn/notation.py +474 -0
  110. openprocess/learn/pack.py +511 -0
  111. openprocess/learn/sheet.py +296 -0
  112. openprocess/mining/__init__.py +73 -0
  113. openprocess/mining/analysis.py +689 -0
  114. openprocess/mining/columns.py +282 -0
  115. openprocess/mining/compare_nets.py +246 -0
  116. openprocess/mining/conformance/__init__.py +0 -0
  117. openprocess/mining/conformance/alignments.py +263 -0
  118. openprocess/mining/conformance/quality.py +145 -0
  119. openprocess/mining/conformance/token_replay.py +252 -0
  120. openprocess/mining/csv_import.py +222 -0
  121. openprocess/mining/definitions.py +584 -0
  122. openprocess/mining/dfg.py +187 -0
  123. openprocess/mining/discovery/__init__.py +0 -0
  124. openprocess/mining/discovery/alpha.py +168 -0
  125. openprocess/mining/discovery/heuristics.py +332 -0
  126. openprocess/mining/discovery/inductive.py +477 -0
  127. openprocess/mining/discovery/state_regions.py +62 -0
  128. openprocess/mining/filtering.py +237 -0
  129. openprocess/mining/footprint.py +183 -0
  130. openprocess/mining/invariants.py +191 -0
  131. openprocess/mining/layout.py +279 -0
  132. openprocess/mining/log.py +364 -0
  133. openprocess/mining/petrinet.py +354 -0
  134. openprocess/mining/playout.py +75 -0
  135. openprocess/mining/pm4py_bridge.py +82 -0
  136. openprocess/mining/pnml.py +223 -0
  137. openprocess/mining/processtree.py +216 -0
  138. openprocess/mining/regions.py +476 -0
  139. openprocess/mining/stats.py +160 -0
  140. openprocess/mining/structure.py +374 -0
  141. openprocess/mining/transition_system.py +409 -0
  142. openprocess/mining/xes.py +399 -0
  143. openprocess/ml/__init__.py +0 -0
  144. openprocess/ml/ast_nodes.py +332 -0
  145. openprocess/ml/builtins.py +364 -0
  146. openprocess/ml/colorsets.py +522 -0
  147. openprocess/ml/errors.py +60 -0
  148. openprocess/ml/evaluator.py +754 -0
  149. openprocess/ml/lexer.py +277 -0
  150. openprocess/ml/multiset.py +417 -0
  151. openprocess/ml/parser.py +737 -0
  152. openprocess/ml/values.py +319 -0
  153. openprocess/model/__init__.py +0 -0
  154. openprocess/model/declarations.py +617 -0
  155. openprocess/model/examples.py +98 -0
  156. openprocess/model/net.py +701 -0
  157. openprocess/model/plain.py +192 -0
  158. openprocess/references.py +280 -0
  159. openprocess/sim/__init__.py +0 -0
  160. openprocess/sim/binding.py +620 -0
  161. openprocess/sim/export.py +66 -0
  162. openprocess/sim/simulator.py +315 -0
  163. openprocess/teaching/__init__.py +4 -0
  164. openprocess/teaching/answers.py +4 -0
  165. openprocess/teaching/checks.py +5 -0
  166. openprocess/teaching/pack.py +4 -0
  167. openprocess/teaching/sheet.py +4 -0
  168. openprocess-0.7.0.dist-info/METADATA +927 -0
  169. openprocess-0.7.0.dist-info/RECORD +173 -0
  170. openprocess-0.7.0.dist-info/WHEEL +5 -0
  171. openprocess-0.7.0.dist-info/entry_points.txt +6 -0
  172. openprocess-0.7.0.dist-info/licenses/LICENSE +21 -0
  173. 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