From e767ac158432ad69ec44241aba7d239ca26b8311 Mon Sep 17 00:00:00 2001 From: Alessandro Berti Date: Tue, 25 Jan 2022 15:03:52 +0100 Subject: [PATCH 1/2] intermediate commit --- pm4py/conformance.py | 41 ++++++++++++++++++++----------- pm4py/convert.py | 11 ++++++--- pm4py/discovery.py | 41 ++++++++++++++++++++----------- pm4py/filtering.py | 58 +++++++++++++++++++++++++++++--------------- pm4py/hof.py | 9 ++++--- pm4py/ml.py | 9 ++++--- pm4py/org.py | 20 +++++++++------ pm4py/stats.py | 55 ++++++++++++++++++++++++++--------------- pm4py/utils.py | 27 ++++++--------------- pm4py/vis.py | 43 ++++++++++++++++++++------------ pm4py/write.py | 7 +++--- 11 files changed, 199 insertions(+), 122 deletions(-) diff --git a/pm4py/conformance.py b/pm4py/conformance.py index 60ef79739..c5d92554b 100644 --- a/pm4py/conformance.py +++ b/pm4py/conformance.py @@ -3,12 +3,13 @@ import deprecation -from pm4py.objects.log.obj import EventLog, Trace, Event +from pm4py.objects.log.obj import EventLog, Trace, Event, EventStream from pm4py.objects.petri_net.obj import PetriNet, Marking from collections import Counter from pm4py.objects.process_tree.obj import ProcessTree from pm4py.util import xes_constants -from pm4py.utils import get_properties, general_checks_classical_event_log +from pm4py.utils import get_properties +import pandas as pd @deprecation.deprecated(deprecated_in='2.2.2', removed_in='2.4.0', @@ -36,7 +37,8 @@ def conformance_tbr(log: EventLog, petri_net: PetriNet, initial_marking: Marking replay_results A list of replay results for each trace of the log """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.conformance.tokenreplay import algorithm as token_replay return token_replay.apply(log, petri_net, initial_marking, final_marking, parameters=get_properties(log)) @@ -63,7 +65,8 @@ def conformance_diagnostics_token_based_replay(log: EventLog, petri_net: PetriNe replay_results A list of replay results for each trace of the log (in the same order as the traces in the event log) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.conformance.tokenreplay import algorithm as token_replay return token_replay.apply(log, petri_net, initial_marking, final_marking, parameters=get_properties(log)) @@ -87,7 +90,8 @@ def conformance_diagnostics_alignments(log: EventLog, *args, multi_processing: b aligned_traces A list of alignments for each trace of the log (in the same order as the traces in the event log) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if len(args) == 3: if type(args[0]) is PetriNet: # Petri net alignments @@ -143,7 +147,8 @@ def conformance_alignments(log: EventLog, petri_net: PetriNet, initial_marking: aligned_traces A list of alignments for each trace of the log """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.conformance.alignments.petri_net import algorithm as alignments return alignments.apply(log, petri_net, initial_marking, final_marking, parameters=get_properties(log)) @@ -172,7 +177,8 @@ def fitness_token_based_replay(log: EventLog, petri_net: PetriNet, initial_marki fitness_dictionary dictionary describing average fitness (key: average_trace_fitness) and the percentage of fitting traces (key: percentage_of_fitting_traces) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.evaluation.replay_fitness import algorithm as replay_fitness return replay_fitness.apply(log, petri_net, initial_marking, final_marking, variant=replay_fitness.Variants.TOKEN_BASED, parameters=get_properties(log)) @@ -203,7 +209,8 @@ def evaluate_fitness_tbr(log: EventLog, petri_net: PetriNet, initial_marking: Ma fitness_dictionary Fitness dictionary (from TBR) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.evaluation.replay_fitness import algorithm as replay_fitness return replay_fitness.apply(log, petri_net, initial_marking, final_marking, variant=replay_fitness.Variants.TOKEN_BASED, parameters=get_properties(log)) @@ -232,7 +239,8 @@ def fitness_alignments(log: EventLog, petri_net: PetriNet, initial_marking: Mark fitness_dictionary dictionary describing average fitness (key: average_trace_fitness) and the percentage of fitting traces (key: percentage_of_fitting_traces) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.evaluation.replay_fitness import algorithm as replay_fitness parameters = get_properties(log) parameters["multiprocessing"] = multi_processing @@ -264,7 +272,8 @@ def evaluate_fitness_alignments(log: EventLog, petri_net: PetriNet, initial_mark fitness_dictionary Fitness dictionary (from alignments) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.evaluation.replay_fitness import algorithm as replay_fitness return replay_fitness.apply(log, petri_net, initial_marking, final_marking, variant=replay_fitness.Variants.ALIGNMENT_BASED, parameters=get_properties(log)) @@ -291,7 +300,8 @@ def precision_token_based_replay(log: EventLog, petri_net: PetriNet, initial_mar precision float representing the precision value """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.evaluation.precision import algorithm as precision_evaluator return precision_evaluator.apply(log, petri_net, initial_marking, final_marking, variant=precision_evaluator.Variants.ETCONFORMANCE_TOKEN, parameters=get_properties(log)) @@ -321,7 +331,8 @@ def evaluate_precision_tbr(log: EventLog, petri_net: PetriNet, initial_marking: precision float representing the precision value """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.evaluation.precision import algorithm as precision_evaluator return precision_evaluator.apply(log, petri_net, initial_marking, final_marking, variant=precision_evaluator.Variants.ETCONFORMANCE_TOKEN, parameters=get_properties(log)) @@ -350,7 +361,8 @@ def precision_alignments(log: EventLog, petri_net: PetriNet, initial_marking: Ma precision float representing the precision value """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.evaluation.precision import algorithm as precision_evaluator parameters = get_properties(log) parameters["multiprocessing"] = multi_processing @@ -383,7 +395,8 @@ def evaluate_precision_alignments(log: EventLog, petri_net: PetriNet, initial_ma precision float representing the precision value """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.evaluation.precision import algorithm as precision_evaluator return precision_evaluator.apply(log, petri_net, initial_marking, final_marking, variant=precision_evaluator.Variants.ALIGN_ETCONFORMANCE, parameters=get_properties(log)) diff --git a/pm4py/convert.py b/pm4py/convert.py index b0da89d5e..091d68caf 100644 --- a/pm4py/convert.py +++ b/pm4py/convert.py @@ -7,7 +7,7 @@ from pm4py.objects.log.obj import EventLog, EventStream from pm4py.objects.petri_net.obj import PetriNet, Marking from pm4py.objects.process_tree.obj import ProcessTree -from pm4py.utils import get_properties, general_checks_classical_event_log +from pm4py.utils import get_properties def convert_to_event_log(obj: Union[pd.DataFrame, EventStream]) -> EventLog: @@ -24,7 +24,8 @@ def convert_to_event_log(obj: Union[pd.DataFrame, EventStream]) -> EventLog: log Event log object """ - general_checks_classical_event_log(obj) + if type(obj) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.objects.conversion.log import converter log = converter.apply(obj, variant=converter.Variants.TO_EVENT_LOG, parameters=get_properties(obj)) return log @@ -44,7 +45,8 @@ def convert_to_event_stream(obj: Union[EventLog, pd.DataFrame]) -> EventStream: stream Event stream object """ - general_checks_classical_event_log(obj) + if type(obj) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.objects.conversion.log import converter stream = converter.apply(obj, variant=converter.Variants.TO_EVENT_STREAM, parameters=get_properties(obj)) return stream @@ -64,7 +66,8 @@ def convert_to_dataframe(obj: Union[EventStream, EventLog]) -> pd.DataFrame: df Dataframe """ - general_checks_classical_event_log(obj) + if type(obj) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.objects.conversion.log import converter df = converter.apply(obj, variant=converter.Variants.TO_DATA_FRAME, parameters=get_properties(obj)) return df diff --git a/pm4py/discovery.py b/pm4py/discovery.py index 3171395a3..e2f2684e2 100644 --- a/pm4py/discovery.py +++ b/pm4py/discovery.py @@ -12,7 +12,7 @@ from pm4py.objects.petri_net.obj import PetriNet, Marking from pm4py.objects.process_tree.obj import ProcessTree from pm4py.util.pandas_utils import check_is_pandas_dataframe, check_pandas_dataframe_columns -from pm4py.utils import get_properties, xes_constants, general_checks_classical_event_log +from pm4py.utils import get_properties, xes_constants from pm4py.objects.ocel.obj import OCEL from pm4py.util import constants @@ -35,7 +35,8 @@ def discover_dfg(log: Union[EventLog, pd.DataFrame]) -> Tuple[dict, dict, dict]: end_activities End activities """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.util import constants @@ -62,7 +63,8 @@ def discover_dfg(log: Union[EventLog, pd.DataFrame]) -> Tuple[dict, dict, dict]: def discover_directly_follows_graph(log: Union[EventLog, pd.DataFrame]) -> Tuple[dict, dict, dict]: - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + return discover_dfg(log) @@ -90,7 +92,8 @@ def discover_performance_dfg(log: Union[EventLog, pd.DataFrame], business_hours: end_activities End activities """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.util import constants @@ -138,7 +141,8 @@ def discover_petri_net_alpha(log: Union[EventLog, pd.DataFrame]) -> Tuple[PetriN final_marking Final marking """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.discovery.alpha import algorithm as alpha_miner return alpha_miner.apply(log, variant=alpha_miner.Variants.ALPHA_VERSION_CLASSIC, parameters=get_properties(log)) @@ -161,7 +165,8 @@ def discover_petri_net_alpha_plus(log: Union[EventLog, pd.DataFrame]) -> Tuple[P final_marking Final marking """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.discovery.alpha import algorithm as alpha_miner return alpha_miner.apply(log, variant=alpha_miner.Variants.ALPHA_VERSION_PLUS, parameters=get_properties(log)) @@ -187,7 +192,8 @@ def discover_petri_net_inductive(log: Union[EventLog, pd.DataFrame], noise_thres final_marking Final marking """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + pt = discover_process_tree_inductive(log, noise_threshold) from pm4py.convert import convert_to_petri_net return convert_to_petri_net(pt) @@ -219,7 +225,8 @@ def discover_petri_net_heuristics(log: Union[EventLog, pd.DataFrame], dependency final_marking Final marking """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.discovery.heuristics import algorithm as heuristics_miner heu_parameters = heuristics_miner.Variants.CLASSIC.value.Parameters parameters = get_properties(log) @@ -246,7 +253,8 @@ def discover_process_tree_inductive(log: Union[EventLog, pd.DataFrame], noise_th process_tree Process tree object """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.discovery.inductive import algorithm as inductive_miner parameters = get_properties(log) parameters[inductive_miner.Variants.IM_CLEAN.value.Parameters.NOISE_THRESHOLD] = noise_threshold @@ -272,7 +280,8 @@ def discover_tree_inductive(log: Union[EventLog, pd.DataFrame], noise_threshold: process_tree Process tree object """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + return discover_process_tree_inductive(log, noise_threshold) @@ -298,7 +307,8 @@ def discover_heuristics_net(log: Union[EventLog, pd.DataFrame], dependency_thres heu_net Heuristics net """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.discovery.heuristics import algorithm as heuristics_miner heu_parameters = heuristics_miner.Variants.CLASSIC.value.Parameters parameters = get_properties(log) @@ -324,7 +334,8 @@ def derive_minimum_self_distance(log: Union[DataFrame, EventLog, EventStream]) - ------- dict mapping an activity to its self-distance, if it exists, otherwise it is not part of the dict. ''' - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.discovery.minimum_self_distance import algorithm as msd return msd.apply(log, parameters=get_properties(log)) @@ -357,7 +368,8 @@ def discover_eventually_follows_graph(log: Union[EventLog, pd.DataFrame]) -> Dic eventually_follows_graph Dictionary of tuples of activities that eventually follows each other; along with the number of occurrences """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.eventually_follows.pandas import get @@ -383,7 +395,8 @@ def discover_bpmn_inductive(log: Union[EventLog, pd.DataFrame], noise_threshold: bpmn_diagram BPMN diagram """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + pt = discover_process_tree_inductive(log, noise_threshold) from pm4py.convert import convert_to_bpmn return convert_to_bpmn(pt) diff --git a/pm4py/filtering.py b/pm4py/filtering.py index a81a8ae98..cff3e70c0 100644 --- a/pm4py/filtering.py +++ b/pm4py/filtering.py @@ -5,10 +5,10 @@ import pandas as pd from pm4py.meta import VERSION as PM4PY_CURRENT_VERSION -from pm4py.objects.log.obj import EventLog +from pm4py.objects.log.obj import EventLog, EventStream from pm4py.util import constants, xes_constants from pm4py.util.pandas_utils import check_is_pandas_dataframe, check_pandas_dataframe_columns -from pm4py.utils import get_properties, general_checks_classical_event_log +from pm4py.utils import get_properties from pm4py.objects.ocel.obj import OCEL import datetime @@ -35,7 +35,8 @@ def filter_log_relative_occurrence_event_attribute(log: Union[EventLog, pd.DataF filtered_log Filtered event log """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) @@ -70,7 +71,8 @@ def filter_start_activities(log: Union[EventLog, pd.DataFrame], activities: Unio filtered_log Filtered log object """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) @@ -105,7 +107,8 @@ def filter_end_activities(log: Union[EventLog, pd.DataFrame], activities: Union filtered_log Filtered log object """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) @@ -151,7 +154,8 @@ def filter_event_attribute_values(log: Union[EventLog, pd.DataFrame], attribute_ filtered_log Filtered log object """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) parameters[constants.PARAMETER_CONSTANT_ATTRIBUTE_KEY] = attribute_key if check_is_pandas_dataframe(log): @@ -203,7 +207,8 @@ def filter_trace_attribute_values(log: Union[EventLog, pd.DataFrame], attribute_ filtered_log Filtered event log """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) parameters[constants.PARAMETER_CONSTANT_ATTRIBUTE_KEY] = attribute_key if check_is_pandas_dataframe(log): @@ -237,7 +242,8 @@ def filter_variants(log: Union[EventLog, pd.DataFrame], variants: Union[Set[str filtered_log Filtered log object """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.util import variants_util parameters = get_properties(log) if variants_util.VARIANT_SPECIFICATION == variants_util.VariantsSpecifications.STRING: @@ -275,7 +281,8 @@ def filter_variants_percentage(log: Union[EventLog, pd.DataFrame], threshold: fl filtered_log Filtered log object """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): raise Exception( "filtering variants percentage on Pandas dataframe is currently not available! please convert the dataframe to event log with the method: log = pm4py.convert_to_event_log(df)") @@ -287,7 +294,8 @@ def filter_variants_percentage(log: Union[EventLog, pd.DataFrame], threshold: fl @deprecation.deprecated(deprecated_in='2.1.3.1', removed_in='2.4.0', current_version=PM4PY_CURRENT_VERSION, details='Use filter_directly_follows_relation') def filter_paths(log, allowed_paths, retain=True): - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + return filter_directly_follows_relation(log, allowed_paths, retain) @@ -313,7 +321,8 @@ def filter_directly_follows_relation(log: Union[EventLog, pd.DataFrame], relatio filtered_log Filtered log object """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) if check_is_pandas_dataframe(log): from pm4py.algo.filtering.pandas.paths import paths_filter @@ -347,7 +356,8 @@ def filter_eventually_follows_relation(log: Union[EventLog, pd.DataFrame], relat filtered_log Filtered log object """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) if check_is_pandas_dataframe(log): from pm4py.algo.filtering.pandas.ltl import ltl_checker @@ -413,7 +423,8 @@ def filter_time_range(log: Union[EventLog, pd.DataFrame], dt1: str, dt2: str, mo filtered_log Filtered log """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): from pm4py.algo.filtering.pandas.timestamp import timestamp_filter if mode == "events": @@ -474,7 +485,8 @@ def filter_between(log: Union[EventLog, pd.DataFrame], act1: str, act2: str) -> filtered_log Log containing all the subcases """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) @@ -504,7 +516,8 @@ def filter_case_size(log: Union[EventLog, pd.DataFrame], min_size: int, max_size filtered_log Log with cases having the desidered number of events. """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) @@ -536,7 +549,8 @@ def filter_case_performance(log: Union[EventLog, pd.DataFrame], min_performance: filtered_log Log with cases having a duration in the specified range """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) @@ -565,7 +579,8 @@ def filter_activities_rework(log: Union[EventLog, pd.DataFrame], activity: str, filtered_log Log with cases having at least min_occurrences occurrences of the given activity """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) parameters["min_occurrences"] = min_occurrences if check_is_pandas_dataframe(log): @@ -601,7 +616,8 @@ def filter_paths_performance(log: Union[EventLog, pd.DataFrame], path: Tuple[str filtered_log Filtered log with the desidered behavior """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) parameters["positive"] = keep parameters["min_performance"] = min_performance @@ -634,7 +650,8 @@ def filter_variants_top_k(log: Union[EventLog, pd.DataFrame], k: int) -> Union[E filtered_log Filtered log """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) @@ -666,7 +683,8 @@ def filter_variants_by_coverage_percentage(log: Union[EventLog, pd.DataFrame], m filtered_log Filtered log """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) diff --git a/pm4py/hof.py b/pm4py/hof.py index 683b2ad46..d7618fe53 100644 --- a/pm4py/hof.py +++ b/pm4py/hof.py @@ -2,7 +2,8 @@ from typing import Callable, Any, Union from pm4py.objects.log import obj as log_inst -from pm4py.utils import general_checks_classical_event_log +import pandas as pd +from pm4py.objects.log.obj import EventLog, EventStream def filter_log(f: Callable[[Any], bool], log: log_inst.EventLog) -> Union[log_inst.EventLog, log_inst.EventStream]: @@ -22,7 +23,8 @@ def filter_log(f: Callable[[Any], bool], log: log_inst.EventLog) -> Union[log_in filtered event log if object provided is correct; original log if not correct """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if isinstance(log, log_inst.EventLog): return log_inst.EventLog(list(filter(f, log)), attributes=log.attributes, classifiers=log.classifiers, omni_present=log.omni_present, extensions=log.extensions, properties=log.properties) @@ -73,7 +75,8 @@ def sort_log(log: log_inst.EventLog, key, reverse: bool = False) -> Union[log_in ------- sorted event log if object provided is correct; original log if not correct """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if isinstance(log, log_inst.EventLog): return log_inst.EventLog(sorted(log, key=key, reverse=reverse), attributes=log.attributes, classifiers=log.classifiers, omni_present=log.omni_present, extensions=log.extensions, properties=log.properties) diff --git a/pm4py/ml.py b/pm4py/ml.py index 3352ecd13..bac819e50 100644 --- a/pm4py/ml.py +++ b/pm4py/ml.py @@ -1,8 +1,7 @@ from typing import Union, Tuple import pandas as pd -from pm4py.objects.log.obj import EventLog +from pm4py.objects.log.obj import EventLog, EventStream from pm4py.util import constants -from pm4py.utils import general_checks_classical_event_log import random @@ -25,7 +24,8 @@ def split_train_test(log: Union[EventLog, pd.DataFrame], train_percentage: float test_log Test event log """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if type(log) is pd.DataFrame: cases = set(log[constants.CASE_CONCEPT_NAME].unique()) train_cases = set() @@ -62,7 +62,8 @@ def get_prefixes_from_log(log: Union[EventLog, pd.DataFrame], length: int) -> Un - if a trace has lower or identical length, it is included as-is - if a trace has greater length, it is cut """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if type(log) is pd.DataFrame: from pm4py.util import pandas_utils log = pandas_utils.insert_ev_in_tr_index(log) diff --git a/pm4py/org.py b/pm4py/org.py index fc3999daf..fca7e8b6d 100644 --- a/pm4py/org.py +++ b/pm4py/org.py @@ -4,7 +4,7 @@ from pm4py.objects.log.obj import EventLog, EventStream from pm4py.util.pandas_utils import check_is_pandas_dataframe, check_pandas_dataframe_columns -from pm4py.utils import get_properties, general_checks_classical_event_log +from pm4py.utils import get_properties from pm4py.util import constants, xes_constants from typing import Dict, Tuple, Any @@ -28,7 +28,8 @@ def discover_handover_of_work_network(log: Union[EventLog, pd.DataFrame], beta=0 metric_values Values of the metric """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.organizational_mining.sna import algorithm as sna parameters = get_properties(log) parameters["beta"] = beta @@ -54,7 +55,8 @@ def discover_working_together_network(log: Union[EventLog, pd.DataFrame]): metric_values Values of the metric """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.organizational_mining.sna import algorithm as sna if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) @@ -77,7 +79,8 @@ def discover_activity_based_resource_similarity(log: Union[EventLog, pd.DataFram metric_values Values of the metric """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.organizational_mining.sna import algorithm as sna if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) @@ -102,7 +105,8 @@ def discover_subcontracting_network(log: Union[EventLog, pd.DataFrame], n=2): metric_values Values of the metric """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.organizational_mining.sna import algorithm as sna parameters = get_properties(log) parameters["n"] = n @@ -131,7 +135,8 @@ def discover_organizational_roles(log: Union[EventLog, pd.DataFrame]): - The second element of the sublist is a dictionary containing the resources of the role and the number of times they executed activities belonging to the role. """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.organizational_mining.roles import algorithm as roles if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) @@ -180,7 +185,8 @@ def discover_network_analysis(log: Union[pd.DataFrame, EventLog, EventStream], o network_analysis Edges of the network analysis (first key: edge; second key: type; value: number of occurrences) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.organizational_mining.network_analysis.variants import dataframe parameters = {} diff --git a/pm4py/stats.py b/pm4py/stats.py index e939d7691..1dfb3a4a6 100644 --- a/pm4py/stats.py +++ b/pm4py/stats.py @@ -5,9 +5,9 @@ import pandas as pd from pm4py.objects.ocel.obj import OCEL -from pm4py.objects.log.obj import EventLog, Trace +from pm4py.objects.log.obj import EventLog, Trace, EventStream from pm4py.util.pandas_utils import check_is_pandas_dataframe, check_pandas_dataframe_columns, insert_ev_in_tr_index -from pm4py.utils import get_properties, general_checks_classical_event_log +from pm4py.utils import get_properties from pm4py.util import xes_constants, constants from copy import copy import deprecation @@ -27,7 +27,8 @@ def get_start_activities(log: Union[EventLog, pd.DataFrame]) -> Dict[str, int]: start_activities Dictionary of start activities along with their count """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.start_activities.pandas import get @@ -51,7 +52,8 @@ def get_end_activities(log: Union[EventLog, pd.DataFrame]) -> Dict[str, int]: end_activities Dictionary of end activities along with their count """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.end_activities.pandas import get @@ -80,7 +82,8 @@ def get_event_attributes(log: Union[EventLog, pd.DataFrame]) -> List[str]: attributes_list List of attributes contained in the log """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) return list(log.columns) @@ -103,7 +106,8 @@ def get_trace_attributes(log: Union[EventLog, pd.DataFrame]) -> List[str]: trace_attributes_list List of attributes at the trace level """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.util import constants if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) @@ -137,7 +141,8 @@ def get_event_attribute_values(log: Union[EventLog, pd.DataFrame], attribute: st attribute_values Dictionary of values along with their count """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + parameters = get_properties(log) parameters["keep_once_per_case"] = count_once_per_case if check_is_pandas_dataframe(log): @@ -165,7 +170,8 @@ def get_trace_attribute_values(log: Union[EventLog, pd.DataFrame], attribute: st attribute_values Dictionary of values along with their count """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.attributes.pandas import get @@ -189,7 +195,8 @@ def get_variants(log: Union[EventLog, pd.DataFrame]) -> Dict[str, List[Trace]]: variants Dictionary of variants along with their count """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + import pm4py if pm4py.util.variants_util.VARIANT_SPECIFICATION == pm4py.util.variants_util.VariantsSpecifications.STRING: import warnings @@ -220,7 +227,8 @@ def get_variants_as_tuples(log: Union[EventLog, pd.DataFrame]) -> Dict[Tuple[str variants Dictionary of variants along with their count """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + import pm4py # the behavior of PM4Py is changed to allow this to work pm4py.util.variants_util.VARIANT_SPECIFICATION = pm4py.util.variants_util.VariantsSpecifications.LIST @@ -248,7 +256,8 @@ def get_minimum_self_distances(log: EventLog) -> Dict[str, int]: ------- dict mapping an activity to its self-distance, if it exists, otherwise it is not part of the dict. ''' - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.discovery.minimum_self_distance import algorithm as msd_algo return msd_algo.apply(log, parameters=get_properties(log)) @@ -272,7 +281,8 @@ def get_minimum_self_distance_witnesses(log: EventLog) -> Dict[str, Set[str]]: Dictionary mapping each activity to a set of witnesses. ''' - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.discovery.minimum_self_distance import algorithm as msd_algo from pm4py.algo.discovery.minimum_self_distance import utils as msdw_algo return msdw_algo.derive_msd_witnesses(log, msd_algo.apply(log, parameters=get_properties(log)), parameters=get_properties(log)) @@ -292,7 +302,8 @@ def get_case_arrival_average(log: Union[EventLog, pd.DataFrame]) -> float: case_arrival_average Average difference between the start times of two consecutive cases """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.traces.generic.pandas import case_arrival @@ -320,7 +331,8 @@ def get_rework_cases_per_activity(log: Union[EventLog, pd.DataFrame]) -> Dict[st Dictionary associating to each of the aforementioned activities the number of cases for which the rework occurred. """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.rework.pandas import get as rework_get @@ -345,7 +357,8 @@ def get_case_overlap(log: Union[EventLog, pd.DataFrame]) -> List[int]: List that for each case (identified by its index in the log) tells how many other cases are concurrently open. """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.overlap.cases.pandas import get as cases_overlap @@ -380,7 +393,8 @@ def get_cycle_time(log: Union[EventLog, pd.DataFrame]) -> float: cycle_time Cycle time (calculated with the aforementioned formula). """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.traces.cycle_time.pandas import get as cycle_time @@ -410,7 +424,8 @@ def get_all_case_durations(log: Union[EventLog, pd.DataFrame], business_hours: b durations Case durations (as list) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + properties = copy(get_properties(log)) properties["business_hours"] = business_hours properties["worktiming"] = worktiming @@ -447,7 +462,8 @@ def get_case_duration(log: Union[EventLog, pd.DataFrame], case_id: str, business duration Duration of the given case """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + properties = copy(get_properties(log)) properties["business_hours"] = business_hours properties["worktiming"] = worktiming @@ -483,7 +499,8 @@ def get_activity_position_summary(log: Union[EventLog, pd.DataFrame], activity: pos_dict_summary Summary of the positions of the activity in the trace (e.g. {1: 1000, 2: 500}) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + properties = get_properties(log) activity_key = properties[ constants.PARAMETER_CONSTANT_ACTIVITY_KEY] if constants.PARAMETER_CONSTANT_ACTIVITY_KEY in properties else xes_constants.DEFAULT_NAME_KEY diff --git a/pm4py/utils.py b/pm4py/utils.py index 9838d86ad..421e71d1f 100644 --- a/pm4py/utils.py +++ b/pm4py/utils.py @@ -39,7 +39,8 @@ def format_dataframe(df: pd.DataFrame, case_id: str = constants.CASE_CONCEPT_NAM df Dataframe """ - general_checks_classical_event_log(df) + if type(df) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.objects.log.util import dataframe_utils if case_id not in df.columns: raise Exception(case_id + " column (case ID) is not in the dataframe!") @@ -220,7 +221,8 @@ def get_properties(log): prop_dict Dictionary containing the properties of the log object """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from copy import copy parameters = copy(log.properties) if hasattr(log, 'properties') else copy(log.attrs) if hasattr(log, 'attrs') else {} @@ -248,7 +250,8 @@ def set_classifier(log, classifier, classifier_attribute=constants.DEFAULT_CLASS log The same event log (methods acts inplace) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if type(classifier) is list: pass elif type(classifier) is str: @@ -346,7 +349,8 @@ def project_on_event_attribute(log: Union[EventLog, pd.DataFrame], attribute_key ['register request', 'examine casually', 'check ticket', 'decide', 'reinitiate request', 'check ticket', 'examine casually', 'decide', 'reinitiate request', 'examine casually', 'check ticket', 'decide', 'reject request'], ['register request', 'check ticket', 'examine thoroughly', 'decide', 'reject request']] """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + output = [] if pandas_utils.check_is_pandas_dataframe(log): pandas_utils.check_pandas_dataframe_columns(log) @@ -360,21 +364,6 @@ def project_on_event_attribute(log: Union[EventLog, pd.DataFrame], attribute_key return output -def general_checks_classical_event_log(log): - """ - Method to checks the consistency of the provided classical event log. - Throws an error if some problems occur. - - Parameters - ----------------- - log - Event log - """ - if type(log) is OCEL: - raise Exception("the method cannot be applied on object-centric event logs!") - return True - - def sample_cases(log: Union[EventLog, pd.DataFrame], num_cases: int) -> Union[EventLog, pd.DataFrame]: """ (Random) Sample a given number of cases from the event log. diff --git a/pm4py/vis.py b/pm4py/vis.py index 0b8aa6c7d..ba41e4f8c 100644 --- a/pm4py/vis.py +++ b/pm4py/vis.py @@ -7,11 +7,11 @@ from pm4py.objects.bpmn.obj import BPMN from pm4py.objects.heuristics_net.obj import HeuristicsNet -from pm4py.objects.log.obj import EventLog +from pm4py.objects.log.obj import EventLog, EventStream from pm4py.objects.petri_net.obj import PetriNet, Marking from pm4py.objects.process_tree.obj import ProcessTree from pm4py.util.pandas_utils import check_is_pandas_dataframe, check_pandas_dataframe_columns -from pm4py.utils import get_properties, general_checks_classical_event_log +from pm4py.utils import get_properties def view_petri_net(petri_net: PetriNet, initial_marking: Optional[Marking] = None, @@ -163,7 +163,8 @@ def save_vis_dfg(dfg: dict, start_activities: dict, end_activities: dict, file_p Destination path """ if log is not None: - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + format = os.path.splitext(file_path)[1][1:] from pm4py.visualization.dfg import visualizer as dfg_visualizer dfg_parameters = dfg_visualizer.Variants.FREQUENCY.value.Parameters @@ -295,7 +296,8 @@ def __dotted_attribute_selection(log, attributes): attributes List of attributes """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if attributes is None: from pm4py.util import xes_constants from pm4py.objects.log.util import sorting @@ -328,7 +330,8 @@ def view_dotted_chart(log, format: str = "png", attributes=None): of the form [x-axis attribute, y-axis attribute, color attribute], e.g., ["concept:name", "org:resource", "concept:name"]) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + log, attributes = __dotted_attribute_selection(log, attributes) from pm4py.visualization.dotted_chart import visualizer as dotted_chart_visualizer gviz = dotted_chart_visualizer.apply(log, attributes, parameters={"format": format}) @@ -348,7 +351,8 @@ def save_vis_dotted_chart(log, file_path: str, attributes=None): attributes Attributes that should be used to construct the dotted chart (for example, ["concept:name", "org:resource"]) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + format = os.path.splitext(file_path)[1][1:] log, attributes = __dotted_attribute_selection(log, attributes) from pm4py.visualization.dotted_chart import visualizer as dotted_chart_visualizer @@ -397,7 +401,8 @@ def view_case_duration_graph(log: Union[EventLog, pd.DataFrame], format: str = " format Format of the visualization (png, svg, ...) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.traces.generic.pandas import case_statistics @@ -422,7 +427,8 @@ def save_vis_case_duration_graph(log: Union[EventLog, pd.DataFrame], file_path: file_path Destination path """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.traces.generic.pandas import case_statistics @@ -448,7 +454,8 @@ def view_events_per_time_graph(log: Union[EventLog, pd.DataFrame], format: str = format Format of the visualization (png, svg, ...) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.attributes.pandas import get as attributes_get @@ -473,7 +480,8 @@ def save_vis_events_per_time_graph(log: Union[EventLog, pd.DataFrame], file_path file_path Destination path """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if check_is_pandas_dataframe(log): check_pandas_dataframe_columns(log) from pm4py.statistics.attributes.pandas import get as attributes_get @@ -499,7 +507,8 @@ def view_performance_spectrum(log: Union[EventLog, pd.DataFrame], activities: Li format Format of the visualization (png, svg ...) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.discovery.performance_spectrum import algorithm as performance_spectrum perf_spectrum = performance_spectrum.apply(log, activities, parameters=get_properties(log)) from pm4py.visualization.performance_spectrum import visualizer as perf_spectrum_visualizer @@ -521,7 +530,8 @@ def save_vis_performance_spectrum(log: Union[EventLog, pd.DataFrame], activities file_path Destination path (including the extension) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.algo.discovery.performance_spectrum import algorithm as performance_spectrum perf_spectrum = performance_spectrum.apply(log, activities, parameters=get_properties(log)) from pm4py.visualization.performance_spectrum import visualizer as perf_spectrum_visualizer @@ -535,7 +545,8 @@ def __builds_events_distribution_graph(log: Union[EventLog, pd.DataFrame], distr """ Internal method to build the events distribution graph """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if distr_type == "days_month": title = "Distribution of the Events over the Days of a Month"; x_axis = "Day of month"; @@ -593,7 +604,8 @@ def view_events_distribution_graph(log: Union[EventLog, pd.DataFrame], distr_typ format Format of the visualization (default: png) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + title, x_axis, y_axis, x, y = __builds_events_distribution_graph(log, distr_type) parameters = copy(get_properties(log)) parameters["title"] = title; @@ -624,7 +636,8 @@ def save_vis_events_distribution_graph(log: Union[EventLog, pd.DataFrame], file_ - hours => Gets the distribution of the events among the hours of a day (from 0 to 23) - days_week => Gets the distribution of the events among the days of a week (from Monday to Sunday) """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + format = os.path.splitext(file_path)[1][1:] title, x_axis, y_axis, x, y = __builds_events_distribution_graph(log, distr_type) parameters = copy(get_properties(log)) diff --git a/pm4py/write.py b/pm4py/write.py index efcaa53f0..cb650f799 100644 --- a/pm4py/write.py +++ b/pm4py/write.py @@ -3,11 +3,11 @@ import deprecation from pm4py.objects.bpmn.obj import BPMN -from pm4py.objects.log.obj import EventLog +from pm4py.objects.log.obj import EventLog, EventStream from pm4py.objects.ocel.obj import OCEL from pm4py.objects.petri_net.obj import PetriNet, Marking from pm4py.objects.process_tree.obj import ProcessTree -from pm4py.utils import general_checks_classical_event_log +import pandas as pd def write_xes(log: EventLog, file_path: str) -> None: @@ -25,7 +25,8 @@ def write_xes(log: EventLog, file_path: str) -> None: ------------- void """ - general_checks_classical_event_log(log) + if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + from pm4py.objects.log.exporter.xes import exporter as xes_exporter xes_exporter.apply(log, file_path) From 9f44bbb7a5b357bc660582ed31a9b04d58605261 Mon Sep 17 00:00:00 2001 From: Alessandro Berti Date: Tue, 25 Jan 2022 15:06:32 +0100 Subject: [PATCH 2/2] fix --- pm4py/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pm4py/utils.py b/pm4py/utils.py index 421e71d1f..c542ce0b3 100644 --- a/pm4py/utils.py +++ b/pm4py/utils.py @@ -221,7 +221,7 @@ def get_properties(log): prop_dict Dictionary containing the properties of the log object """ - if type(log) not in [pd.DataFrame, EventLog, EventStream]: raise Exception("the method can be applied only to a traditional event log!") + if type(log) not in [pd.DataFrame, EventLog, EventStream]: return {} from copy import copy parameters = copy(log.properties) if hasattr(log, 'properties') else copy(log.attrs) if hasattr(log,