def initialize_tree(self, dfg, initial_dfg, activities, second_iteration=False): """ Initialize the tree Parameters ----------- dfg Directly follows graph of this subtree initial_dfg Referral directly follows graph that should be taken in account adding hidden/loop transitions activities Activities of this subtree second_iteration Boolean that indicates if we are executing this method for the second time """ self.second_iteration = second_iteration if activities is None: self.activities = get_activities_from_dfg(dfg) else: self.activities = copy(activities) if second_iteration: self.dfg = clean_dfg_based_on_noise_thresh(self.dfg, self.activities, self.noise_threshold) else: self.dfg = copy(dfg) self.initial_dfg = initial_dfg self.outgoing = get_outgoing_edges(self.dfg) self.ingoing = get_ingoing_edges(self.dfg) self.self_loop_activities = get_activities_self_loop(self.dfg) self.initial_outgoing = get_outgoing_edges(self.initial_dfg) self.initial_ingoing = get_ingoing_edges(self.initial_dfg) self.activities_direction = get_activities_direction( self.dfg, self.activities) self.activities_dir_list = get_activities_dirlist( self.activities_direction) self.negated_dfg = negate(self.dfg) self.negated_activities = get_activities_from_dfg(self.negated_dfg) self.negated_outgoing = get_outgoing_edges(self.negated_dfg) self.negated_ingoing = get_ingoing_edges(self.negated_dfg) self.detected_cut = None self.children = [] if second_iteration: self.detect_cut(second_iteration=second_iteration)
def initialize_tree(self): """ Initialize the tree """ if self.activities is None: self.activities = list(set(y for x in self.traces for y in x)) else: if self.parent is not None and self.parent.detected_cut_add_info == "loop": self.get_traces_loop() else: self.traces = self.get_traces_general() if self.second_iteration: self.traces, self.activities = self.clean_traces_noise() self.start_activities = list(set(x[0] for x in self.traces if x)) self.end_activities = list(set(x[-1] for x in self.traces if x)) self.activities_occurrences = Counter( [y for x in self.traces for y in x]) self.dfg = Counter( (x[i - 1], x[i]) for x in self.traces for i in range(1, len(x))) self.dfg = [(x, y) for x, y in self.dfg.items()] self.initial_dfg = self.dfg self.outgoing = get_outgoing_edges(self.dfg) self.ingoing = get_ingoing_edges(self.dfg) self.self_loop_activities = get_activities_self_loop(self.dfg) self.activities_direction = get_activities_direction( self.dfg, self.activities) self.activities_dir_list = get_activities_dirlist( self.activities_direction) self.negated_dfg = negate(self.dfg) self.negated_activities = get_activities_from_dfg(self.negated_dfg) self.negated_outgoing = get_outgoing_edges(self.negated_dfg) self.negated_ingoing = get_ingoing_edges(self.negated_dfg) self.contains_empty_traces = min( len(x) for x in self.traces) == 0 if len(self.traces) > 0 else False self.must_insert_skip = self.contains_empty_traces if self.parent is not None and self.parent.detected_cut == "xor": self.must_insert_skip = False self.must_insert_skip = self.rec_must_insert_skip or self.must_insert_skip if not self.second_iteration: self.second_tree = self.clone_second_it() self.detected_cut = None self.children = []
def check_loop_need(spec_tree_struct): """ Check whether a forced loop transitions shall be added Parameters ----------- spec_tree_struct Internal tree structure (after application of Inductive Miner) Returns ----------- need_loop_on_subtree Checks if the loop on the subtree is needed """ self_loop_activities = set(get_activities_self_loop(spec_tree_struct.initial_dfg)) self_loop_activities = self_loop_activities.intersection(set(spec_tree_struct.activities)) need_loop_on_subtree = len(self_loop_activities) > 0 return need_loop_on_subtree