diff --git a/Ficus/src/rust/ficus/src/pipelines/activities_parts.rs b/Ficus/src/rust/ficus/src/pipelines/activities_parts.rs index 9e0253d1..2e2b89a4 100644 --- a/Ficus/src/rust/ficus/src/pipelines/activities_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/activities_parts.rs @@ -24,6 +24,7 @@ use crate::{ repeat_sets::{build_repeat_set_tree_from_repeats, build_repeat_sets}, }, }, + pipeline_part, pipelines::{ context::PipelineInfrastructure, keys::context_keys::{ @@ -80,12 +81,10 @@ impl FromStr for ActivitiesLogsSourceDto { } impl PipelineParts { - pub(super) fn discover_activities() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ACTIVITIES, &|context, _, config| { - let activity_level = Self::get_user_data(config, &ACTIVITY_LEVEL_KEY)?; - Self::do_discover_activities(context, *activity_level, config) - }) - } + pipeline_part!(discover_activities, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let activity_level = Self::get_user_data(config, &ACTIVITY_LEVEL_KEY)?; + Self::do_discover_activities(context, *activity_level, config) + }); pub(super) fn do_discover_activities( context: &mut PipelineContext, @@ -116,12 +115,13 @@ impl PipelineParts { Ok(()) } - pub(super) fn discover_activities_instances() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ACTIVITIES_INSTANCES, &|context, _, config| { + pipeline_part!( + discover_activities_instances, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::do_discover_activities_instances(context, config)?; Ok(()) - }) - } + } + ); pub(super) fn do_discover_activities_instances( context: &mut PipelineContext, @@ -149,12 +149,10 @@ impl PipelineParts { Ok(()) } - pub(super) fn create_log_from_activities() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CREATE_LOG_FROM_ACTIVITIES, &|context, _, config| { - Self::do_create_log_from_activities(context, config)?; - Ok(()) - }) - } + pipeline_part!(create_log_from_activities, &|context, _, config| { + Self::do_create_log_from_activities(context, config)?; + Ok(()) + }); pub(super) fn do_create_log_from_activities( context: &mut PipelineContext, @@ -192,8 +190,9 @@ impl PipelineParts { Ok(()) } - pub(super) fn discover_activities_instances_for_several_levels() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ACTIVITIES_FOR_SEVERAL_LEVEL, &|context, infra, config| { + pipeline_part!( + discover_activities_for_several_levels, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let event_classes = Self::get_user_data(config, ®EXES_KEY)?; let initial_activity_level = *Self::get_user_data(config, &ACTIVITY_LEVEL_KEY)?; let patterns_kind = Self::get_user_data(config, &PATTERNS_KIND_KEY)?; @@ -223,8 +222,8 @@ impl PipelineParts { } Ok(()) - }) - } + } + ); pub(super) fn adjust_with_activities_from_unattached_events( old_context: &mut PipelineContext, @@ -266,8 +265,9 @@ impl PipelineParts { Ok(()) } - pub(super) fn discover_activities_in_unattached_subtraces() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ACTIVITIES_IN_UNATTACHED_SUBTRACES, &|context, _, config| { + pipeline_part!( + discover_activities_in_unattached_subtraces, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let mut existing_activities = &Self::create_empty_activities(log); @@ -296,8 +296,8 @@ impl PipelineParts { context.put_concrete(TRACE_ACTIVITIES_KEY.key(), new_activities); Ok(()) - }) - } + } + ); pub(super) fn create_add_unattached_events_part(&self, config: UserDataImpl) -> DefaultPipelinePart { let name = Self::DISCOVER_ACTIVITIES_IN_UNATTACHED_SUBTRACES; @@ -315,12 +315,10 @@ impl PipelineParts { activities } - pub(super) fn clear_activities_related_stuff() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLEAR_ACTIVITIES, &|context, _, _| { - Self::do_clear_activities_related_stuff(context); - Ok(()) - }) - } + pipeline_part!(clear_activities, |context: &mut PipelineContext, _, _| { + Self::do_clear_activities_related_stuff(context); + Ok(()) + }); pub(super) fn do_clear_activities_related_stuff(context: &mut PipelineContext) { context.remove_concrete(ACTIVITIES_KEY.key()); @@ -329,16 +327,16 @@ impl PipelineParts { context.remove_concrete(REPEAT_SETS_KEY.key()); } - pub(super) fn get_number_of_underlying_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::GET_UNDERLYING_EVENTS_COUNT, &|context, infra, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let count = count_underlying_events(log); - infra.log(format!("Number of underlying events: {}", &count).as_str())?; + pipeline_part!(get_underlying_events_count, |context: &mut PipelineContext, + infra: &PipelineInfrastructure, + _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let count = count_underlying_events(log); + infra.log(format!("Number of underlying events: {}", &count).as_str())?; - context.put_concrete(UNDERLYING_EVENTS_COUNT_KEY.key(), count); - Ok(()) - }) - } + context.put_concrete(UNDERLYING_EVENTS_COUNT_KEY.key(), count); + Ok(()) + }); pub(super) fn execute_with_activities_instances( activities: &Vec, @@ -362,8 +360,9 @@ impl PipelineParts { Ok(()) } - pub(super) fn discover_activities_until_no_more() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ACTIVITIES_UNTIL_NO_MORE, &|context, infra, config| { + pipeline_part!( + discover_activities_until_no_more, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let activity_level = *Self::get_user_data(config, &ACTIVITY_LEVEL_KEY)?; let after_activities_extraction_pipeline = Self::get_user_data(config, &PIPELINE_KEY); let execute_only_after_last_extraction = *Self::get_user_data(config, &EXECUTE_ONLY_ON_LAST_EXTRACTION_KEY)?; @@ -413,11 +412,12 @@ impl PipelineParts { return Ok(()); } } - }) - } + } + ); - pub(super) fn execute_with_each_activity_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::EXECUTE_WITH_EACH_ACTIVITY_LOG, &|context, infra, config| { + pipeline_part!( + execute_with_each_activity_log, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; let activities_to_logs = Self::create_activities_to_logs(context, config)?; @@ -430,8 +430,8 @@ impl PipelineParts { } Ok(()) - }) - } + } + ); fn create_activities_to_logs( context: &mut PipelineContext, @@ -452,69 +452,66 @@ impl PipelineParts { } } - pub(super) fn substitute_underlying_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SUBSTITUTE_UNDERLYING_EVENTS, &|context, _, _| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let mut new_log = XesEventLogImpl::empty(); + pipeline_part!(substitute_underlying_events, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + let mut new_log = XesEventLogImpl::empty(); - for trace in log.traces() { - let mut new_trace = XesTraceImpl::empty(); - for event in trace.borrow().events() { - substitute_underlying_events(event, &mut new_trace); - } - - new_log.push(Rc::new(RefCell::new(new_trace))); + for trace in log.traces() { + let mut new_trace = XesTraceImpl::empty(); + for event in trace.borrow().events() { + substitute_underlying_events(event, &mut new_trace); } - context.put_concrete(EVENT_LOG_KEY.key(), new_log); - Ok(()) - }) - } + new_log.push(Rc::new(RefCell::new(new_trace))); + } - pub(super) fn apply_class_extractor() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::APPLY_CLASS_EXTRACTOR, &|context, _, config| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + context.put_concrete(EVENT_LOG_KEY.key(), new_log); + Ok(()) + }); - let event_class_regex = Self::get_user_data(config, &EVENT_CLASS_REGEX_KEY)?; - let event_class_regex = Self::try_parse_regex(event_class_regex)?; + pipeline_part!(apply_class_extractor, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let filter_regex = Self::get_user_data(config, ®EX_KEY)?; - let filter_regex = Self::try_parse_regex(filter_regex)?; + let event_class_regex = Self::get_user_data(config, &EVENT_CLASS_REGEX_KEY)?; + let event_class_regex = Self::try_parse_regex(event_class_regex)?; - for trace in log.traces() { - for event in trace.borrow().events() { - if !filter_regex.is_match(event.borrow().name()).ok().unwrap() { - continue; - } + let filter_regex = Self::get_user_data(config, ®EX_KEY)?; + let filter_regex = Self::try_parse_regex(filter_regex)?; - let borrowed_event = event.borrow(); - let found_match = event_class_regex.find(borrowed_event.name()); - if found_match.is_err() { - continue; - } + for trace in log.traces() { + for event in trace.borrow().events() { + if !filter_regex.is_match(event.borrow().name()).ok().unwrap() { + continue; + } - let (start, end) = if let Ok(Some(found_match)) = found_match { - (found_match.start(), found_match.end()) - } else { - (0, borrowed_event.name().len()) - }; + let borrowed_event = event.borrow(); + let found_match = event_class_regex.find(borrowed_event.name()); + if found_match.is_err() { + continue; + } - drop(found_match); - drop(borrowed_event); + let (start, end) = if let Ok(Some(found_match)) = found_match { + (found_match.start(), found_match.end()) + } else { + (0, borrowed_event.name().len()) + }; - if start == 0 { - let new_name = event.borrow().name()[start..end].to_owned(); - event.borrow_mut().set_name(new_name); - } + drop(found_match); + drop(borrowed_event); + + if start == 0 { + let new_name = event.borrow().name()[start..end].to_owned(); + event.borrow_mut().set_name(new_name); } } + } - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn serialize_activities_logs() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SERIALIZE_ACTIVITIES_LOGS, &|context, _, config| { + pipeline_part!( + serialize_activities_logs, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let logs_to_activities = Self::create_activities_to_logs(context, config)?; let path = Path::new(Self::get_user_data(config, &PATH_KEY)?); let format = Self::get_user_data(config, &LOG_SERIALIZATION_FORMAT_KEY)?; @@ -539,11 +536,12 @@ impl PipelineParts { } Ok(()) - }) - } + } + ); - pub(super) fn reverse_hierarchy_indices() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::REVERSE_HIERARCHY_INDICES, &|context, _, _| { + pipeline_part!( + reverse_hierarchy_indices, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; const HIERARCHY_LEVEL: &str = "hierarchy_level_"; @@ -591,6 +589,6 @@ impl PipelineParts { } Ok(()) - }) - } + } + ); } diff --git a/Ficus/src/rust/ficus/src/pipelines/annotations_parts.rs b/Ficus/src/rust/ficus/src/pipelines/annotations_parts.rs index 479948d4..279fb065 100644 --- a/Ficus/src/rust/ficus/src/pipelines/annotations_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/annotations_parts.rs @@ -9,6 +9,7 @@ use crate::{ petri_net::DefaultPetriNet, }, }, + pipeline_part, pipelines::{ context::PipelineContext, errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError}, @@ -27,16 +28,17 @@ use crate::{ }; impl PipelineParts { - pub(super) fn annotate_petri_net_count() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ANNOTATE_PETRI_NET_COUNT, &|context, _, config| { + pipeline_part!( + annotate_petri_net_count, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::annotate_petri_net( &PETRI_NET_COUNT_ANNOTATION_KEY, context, config, |log, net, terminate_on_unreplayable_traces| annotate_with_counts(log, net, terminate_on_unreplayable_traces), ) - }) - } + } + ); fn annotate_petri_net( annotation_key: &DefaultContextKey>, @@ -58,30 +60,33 @@ impl PipelineParts { } } - pub(super) fn annotate_petri_net_frequency() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ANNOTATE_PETRI_NET_FREQUENCY, &|context, _, config| { + pipeline_part!( + annotate_petri_net_frequency, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::annotate_petri_net( &PETRI_NET_FREQUENCY_ANNOTATION_KEY, context, config, |log, net, terminate_on_unreplayable_traces| annotate_with_frequencies(log, net, terminate_on_unreplayable_traces), ) - }) - } + } + ); - pub(super) fn annotate_petri_net_trace_frequency() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ANNOTATE_PETRI_NET_TRACE_FREQUENCY, &|context, _, config| { + pipeline_part!( + annotate_petri_net_trace_frequency, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::annotate_petri_net( &PETRI_NET_TRACE_FREQUENCY_ANNOTATION_KEY, context, config, |log, net, terminate_on_unreplayable_traces| annotate_with_trace_frequency(log, net, terminate_on_unreplayable_traces), ) - }) - } + } + ); - pub(super) fn annotate_graph_with_time_performance() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ANNOTATE_GRAPH_WITH_TIME, &|context, _, config| { + pipeline_part!( + annotate_graph_with_time, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let graph = Self::get_user_data(context, &GRAPH_KEY)?; let annotation_kind = *Self::get_user_data(config, &TIME_ANNOTATION_KIND_KEY)?; @@ -96,23 +101,21 @@ impl PipelineParts { Ok(()) } } - }) - } + } + ); - pub(super) fn create_ocel_annotation_for_dag() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CREATE_OCEL_ANNOTATION_FOR_DAG, &|context, _, _| { - let graph = Self::get_user_data(context, &GRAPH_KEY)?; + pipeline_part!(create_ocel_annotation_for_dag, |context: &mut PipelineContext, _, _| { + let graph = Self::get_user_data(context, &GRAPH_KEY)?; - match create_ocel_annotation_for_dag(graph) { - Ok(annotation) => { - context.put_concrete(OCEL_ANNOTATION_KEY.key(), annotation); - Ok(()) - } - Err(err) => { - let message = format!("Failed to create ocel annotation, error: {}", err.to_string()); - Err(PipelinePartExecutionError::new_raw(message)) - } + match create_ocel_annotation_for_dag(graph) { + Ok(annotation) => { + context.put_concrete(OCEL_ANNOTATION_KEY.key(), annotation); + Ok(()) } - }) - } + Err(err) => { + let message = format!("Failed to create ocel annotation, error: {}", err.to_string()); + Err(PipelinePartExecutionError::new_raw(message)) + } + } + }); } diff --git a/Ficus/src/rust/ficus/src/pipelines/cases.rs b/Ficus/src/rust/ficus/src/pipelines/cases.rs index 4e5bc196..8dac1a2c 100644 --- a/Ficus/src/rust/ficus/src/pipelines/cases.rs +++ b/Ficus/src/rust/ficus/src/pipelines/cases.rs @@ -1,30 +1,32 @@ use crate::{ features::cases::cases_discovery::discover_cases, + pipeline_part, pipelines::{ + context::{PipelineContext, PipelineInfrastructure}, keys::context_keys::{END_CASE_REGEX_KEY, EVENT_LOG_KEY, INLINE_INNER_CASES_KEY, PIPELINE_KEY, START_CASE_REGEX_KEY}, pipeline_parts::PipelineParts, pipelines::{PipelinePart, PipelinePartFactory}, }, - utils::user_data::user_data::UserData, + utils::user_data::user_data::{UserData, UserDataImpl}, }; impl PipelineParts { - pub(super) fn discover_cases() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_CASES, &|context, infra, config| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; - let start_case_regex = Self::get_user_data(config, &START_CASE_REGEX_KEY)?; - let end_case_regex = Self::get_user_data(config, &END_CASE_REGEX_KEY)?; - let inline_inner_cases = *Self::get_user_data(config, &INLINE_INNER_CASES_KEY)?; + pipeline_part!(discover_cases, |context: &mut PipelineContext, + infra: &PipelineInfrastructure, + config: &UserDataImpl| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; + let start_case_regex = Self::get_user_data(config, &START_CASE_REGEX_KEY)?; + let end_case_regex = Self::get_user_data(config, &END_CASE_REGEX_KEY)?; + let inline_inner_cases = *Self::get_user_data(config, &INLINE_INNER_CASES_KEY)?; - let new_log = discover_cases(log, start_case_regex.as_str(), end_case_regex.as_str(), inline_inner_cases); + let new_log = discover_cases(log, start_case_regex.as_str(), end_case_regex.as_str(), inline_inner_cases); - let mut new_context = context.clone(); - new_context.put_concrete(EVENT_LOG_KEY.key(), new_log); + let mut new_context = context.clone(); + new_context.put_concrete(EVENT_LOG_KEY.key(), new_log); - pipeline.execute(&mut new_context, infra)?; + pipeline.execute(&mut new_context, infra)?; - Ok(()) - }) - } + Ok(()) + }); } diff --git a/Ficus/src/rust/ficus/src/pipelines/clustering.rs b/Ficus/src/rust/ficus/src/pipelines/clustering.rs index 4e2bd20b..f6785385 100644 --- a/Ficus/src/rust/ficus/src/pipelines/clustering.rs +++ b/Ficus/src/rust/ficus/src/pipelines/clustering.rs @@ -14,6 +14,7 @@ use crate::{ traces_params::{FeatureCountKind, TracesClusteringParams}, }, }, + pipeline_part, pipelines::{ context::{PipelineContext, PipelineInfrastructure}, errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError}, @@ -32,8 +33,9 @@ use crate::{ }; impl PipelineParts { - pub(super) fn clusterize_activities_from_traces_k_means() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_ACTIVITIES_FROM_TRACES_KMEANS, &|context, _, config| { + pipeline_part!( + clusterize_activities_from_traces_kmeans, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let mut params = Self::create_activities_clustering_params(context, config)?; let clusters_count = *Self::get_user_data(config, &CLUSTERS_COUNT_KEY)? as usize; let learning_iterations_count = *Self::get_user_data(config, &LEARNING_ITERATIONS_COUNT_KEY)? as usize; @@ -45,8 +47,8 @@ impl PipelineParts { context.put_concrete(LABELED_TRACES_ACTIVITIES_DATASET_KEY.key(), labeled_dataset); Ok(()) - }) - } + } + ); fn create_common_vis_params<'a>( context: &'a PipelineContext, @@ -99,8 +101,9 @@ impl PipelineParts { } } - pub(super) fn clusterize_activities_from_traces_k_means_grid_search() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_ACTIVITIES_FROM_TRACES_KMEANS_GRID_SEARCH, &|context, _, config| { + pipeline_part!( + clusterize_activities_from_traces_kmeans_grid_search, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let learning_iterations_count = *Self::get_user_data(config, &LEARNING_ITERATIONS_COUNT_KEY)? as usize; let mut params = Self::create_activities_clustering_params(context, config)?; @@ -111,11 +114,12 @@ impl PipelineParts { context.put_concrete(LABELED_TRACES_ACTIVITIES_DATASET_KEY.key(), labeled_dataset); Ok(()) - }) - } + } + ); - pub(super) fn clusterize_activities_from_traces_dbscan() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_ACTIVITIES_FROM_TRACES_DBSCAN, &|context, _, config| { + pipeline_part!( + clusterize_activities_from_traces_dbscan, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let min_points_in_cluster = *Self::get_user_data(config, &MIN_EVENTS_IN_CLUSTERS_COUNT_KEY)? as usize; let put_noise_events_in_one_cluster = *Self::get_user_data(config, &PUT_NOISE_EVENTS_IN_ONE_CLUSTER_KEY)?; let mut params = Self::create_activities_clustering_params(context, config)?; @@ -127,11 +131,12 @@ impl PipelineParts { context.put_concrete(LABELED_TRACES_ACTIVITIES_DATASET_KEY.key(), labeled_dataset); Ok(()) - }) - } + } + ); - pub fn clusterize_log_by_traces_k_means_grid_search() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_LOG_TRACES_K_MEANS_GRID_SEARCH, &|context, infra, config| { + pipeline_part!( + clusterize_log_traces_k_means_grid_search, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let mut params = Self::create_traces_clustering_params(context, config)?; let learning_iterations_count = *Self::get_user_data(config, &LEARNING_ITERATIONS_COUNT_KEY)? as u64; let tolerance = *Self::get_user_data(config, &TOLERANCE_KEY)?; @@ -153,11 +158,12 @@ impl PipelineParts { context.put_concrete(LABELED_LOG_TRACES_DATASET_KEY.key(), labeled_dataset); Ok(()) - }) - } + } + ); - pub(super) fn create_traces_activities_dataset() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CREATE_TRACES_ACTIVITIES_DATASET, &|context, _, config| { + pipeline_part!( + create_traces_activities_dataset, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let params = Self::create_activities_visualization_params(context, config)?; let (dataset, processed, classes) = match create_dataset(¶ms) { @@ -170,8 +176,8 @@ impl PipelineParts { context.put_concrete(TRACES_ACTIVITIES_DATASET_KEY.key(), ficus_dataset); Ok(()) - }) - } + } + ); pub(crate) fn create_traces_clustering_params<'a>( context: &'a mut PipelineContext, @@ -198,8 +204,9 @@ impl PipelineParts { }) } - pub(super) fn clusterize_log_traces() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_LOG_TRACES, &|context, infra, config| { + pipeline_part!( + clusterize_log_traces, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let mut params = Self::create_traces_clustering_params(context, config)?; let after_clusterization_pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; let min_points_in_cluster = *Self::get_user_data(config, &MIN_EVENTS_IN_CLUSTERS_COUNT_KEY)? as usize; @@ -216,11 +223,12 @@ impl PipelineParts { Self::execute_with_temp_event_logs(context, infra, new_logs.0, after_clusterization_pipeline)?; Ok(()) - }) - } + } + ); - pub(super) fn clusterize_log_traces_dbscan_grid_search() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLUSTERIZE_LOG_TRACES_DBSCAN_GRID_SEARCH, &|context, infra, config| { + pipeline_part!( + clusterize_log_traces_dbscan_grid_search, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let mut params = Self::create_traces_clustering_params(context, config)?; let after_clusterization_pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; @@ -241,8 +249,8 @@ impl PipelineParts { Self::execute_with_temp_event_logs(context, infra, new_logs.0, after_clusterization_pipeline)?; Ok(()) - }) - } + } + ); fn execute_with_temp_event_logs( context: &mut PipelineContext, diff --git a/Ficus/src/rust/ficus/src/pipelines/discovery_parts.rs b/Ficus/src/rust/ficus/src/pipelines/discovery_parts.rs index 2bc95f10..5b317a6d 100644 --- a/Ficus/src/rust/ficus/src/pipelines/discovery_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/discovery_parts.rs @@ -17,6 +17,7 @@ use crate::{ root_sequence::discovery_xes::discover_root_sequence_graph_from_event_log, }, }, + pipeline_part, pipelines::{ context::PipelineContext, errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError}, @@ -30,53 +31,45 @@ use crate::{ pipeline_parts::PipelineParts, pipelines::PipelinePartFactory, }, - utils::user_data::user_data::UserData, + utils::user_data::user_data::{UserData, UserDataImpl}, }; impl PipelineParts { - pub(super) fn discover_petri_net_alpha() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_ALPHA, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let event_log_info = OfflineEventLogInfo::create_from(EventLogInfoCreationDto::default(log)); - let provider = DefaultAlphaRelationsProvider::new(&event_log_info); - let discovered_net = discover_petri_net_alpha(&provider); + pipeline_part!(discover_petri_net_alpha, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let event_log_info = OfflineEventLogInfo::create_from(EventLogInfoCreationDto::default(log)); + let provider = DefaultAlphaRelationsProvider::new(&event_log_info); + let discovered_net = discover_petri_net_alpha(&provider); - context.put_concrete(PETRI_NET_KEY.key(), discovered_net); + context.put_concrete(PETRI_NET_KEY.key(), discovered_net); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn discover_petri_net_alpha_stream() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_ALPHA_STREAM, &|context, _, _| { - let event_log_info = Self::get_user_data(context, &EVENT_LOG_INFO_KEY)?; - let provider = DefaultAlphaRelationsProvider::new(event_log_info); - let discovered_net = discover_petri_net_alpha(&provider); + pipeline_part!(discover_petri_net_alpha_stream, |context: &mut PipelineContext, _, _| { + let event_log_info = Self::get_user_data(context, &EVENT_LOG_INFO_KEY)?; + let provider = DefaultAlphaRelationsProvider::new(event_log_info); + let discovered_net = discover_petri_net_alpha(&provider); - context.put_concrete(PETRI_NET_KEY.key(), discovered_net); + context.put_concrete(PETRI_NET_KEY.key(), discovered_net); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn serialize_petri_net() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SERIALIZE_PETRI_NET, &|context, _, config| { - let petri_net = Self::get_user_data(context, &PETRI_NET_KEY)?; - let save_path = Self::get_user_data(config, &PATH_KEY)?; - let use_names_as_ids = *Self::get_user_data(config, &PNML_USE_NAMES_AS_IDS_KEY)?; + pipeline_part!(serialize_petri_net, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let petri_net = Self::get_user_data(context, &PETRI_NET_KEY)?; + let save_path = Self::get_user_data(config, &PATH_KEY)?; + let use_names_as_ids = *Self::get_user_data(config, &PNML_USE_NAMES_AS_IDS_KEY)?; - match serialize_to_pnml_file(petri_net, save_path, use_names_as_ids) { - Ok(_) => Ok(()), - Err(error) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(error.to_string()))), - } - }) - } + match serialize_to_pnml_file(petri_net, save_path, use_names_as_ids) { + Ok(_) => Ok(()), + Err(error) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(error.to_string()))), + } + }); - pub(super) fn discover_petri_net_alpha_plus() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_ALPHA_PLUS, &|context, _, _| { - Self::do_discover_petri_net_alpha_plus(context, false) - }) - } + pipeline_part!(discover_petri_net_alpha_plus, |context: &mut PipelineContext, _, _| { + Self::do_discover_petri_net_alpha_plus(context, false) + }); fn do_discover_petri_net_alpha_plus(context: &mut PipelineContext, alpha_plus_plus: bool) -> Result<(), PipelinePartExecutionError> { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; @@ -98,47 +91,40 @@ impl PipelineParts { Ok(()) } - pub(super) fn discover_petri_net_alpha_plus_plus() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_ALPHA_PLUS_PLUS, &|context, _, _| { - Self::do_discover_petri_net_alpha_plus(context, true) - }) - } + pipeline_part!(discover_petri_net_alpha_plus_plus, |context: &mut PipelineContext, _, _| { + Self::do_discover_petri_net_alpha_plus(context, true) + }); - pub(super) fn discover_petri_net_alpha_plus_plus_nfc() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_ALPHA_PLUS_PLUS_NFC, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let discovered_petri_net = discover_petri_net_alpha_plus_plus_nfc(log); - context.put_concrete(PETRI_NET_KEY.key(), discovered_petri_net); + pipeline_part!(discover_petri_net_alpha_plus_plus_nfc, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let discovered_petri_net = discover_petri_net_alpha_plus_plus_nfc(log); + context.put_concrete(PETRI_NET_KEY.key(), discovered_petri_net); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn discover_directly_follows_graph() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_DFG, &|context, _, config| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let creation_dto = match Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY) { - Ok(thread_attribute) => EventLogInfoCreationDto::default_thread(log, thread_attribute.to_owned()), - Err(_) => EventLogInfoCreationDto::default(log), - }; + pipeline_part!(discover_dfg, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let creation_dto = match Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY) { + Ok(thread_attribute) => EventLogInfoCreationDto::default_thread(log, thread_attribute.to_owned()), + Err(_) => EventLogInfoCreationDto::default(log), + }; - context.put_concrete(GRAPH_KEY.key(), construct_dfg(&OfflineEventLogInfo::create_from(creation_dto))); + context.put_concrete(GRAPH_KEY.key(), construct_dfg(&OfflineEventLogInfo::create_from(creation_dto))); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn discover_directly_follows_graph_stream() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_DFG_STREAM, &|context, _, _| { - let info = Self::get_user_data(context, &EVENT_LOG_INFO_KEY)?; - context.put_concrete(GRAPH_KEY.key(), construct_dfg(info)); + pipeline_part!(discover_dfg_stream, |context: &mut PipelineContext, _, _| { + let info = Self::get_user_data(context, &EVENT_LOG_INFO_KEY)?; + context.put_concrete(GRAPH_KEY.key(), construct_dfg(info)); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn discover_directly_follows_graph_by_attribute() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_DFG_BY_ATTRIBUTE, &|context, _, config| { + pipeline_part!( + discover_dfg_by_attribute, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let attribute = Self::get_user_data(config, &ATTRIBUTE_KEY)?; let dfg = construct_dfg_by_attribute(log, attribute); @@ -146,11 +132,12 @@ impl PipelineParts { context.put_concrete(GRAPH_KEY.key(), dfg); Ok(()) - }) - } + } + ); - pub(super) fn discover_petri_net_heuristic_miner() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_PETRI_NET_HEURISTIC, &|context, _, config| { + pipeline_part!( + discover_petri_net_heuristic, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let dependency_threshold = *Self::get_user_data(config, &DEPENDENCY_THRESHOLD_KEY)?; let positive_observations_threshold = *Self::get_user_data(config, &POSITIVE_OBSERVATIONS_THRESHOLD_KEY)? as usize; @@ -174,49 +161,46 @@ impl PipelineParts { context.put_concrete(PETRI_NET_KEY.key(), petri_net); Ok(()) - }) - } - - pub(super) fn discover_fuzzy_graph() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_FUZZY_GRAPH, &|context, _, config| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let unary_freq_threshold = *Self::get_user_data(config, &UNARY_FREQUENCY_THRESHOLD_KEY)?; - let binary_sig_threshold = *Self::get_user_data(config, &BINARY_FREQUENCY_SIGNIFICANCE_THRESHOLD_KEY)?; - let preserve_ratio = *Self::get_user_data(config, &PRESERVE_THRESHOLD_KEY)?; - let ratio_threshold = *Self::get_user_data(config, &RATIO_THRESHOLD_KEY)?; - let utility_rate = *Self::get_user_data(config, &UTILITY_RATE_KEY)?; - let edge_cutoff_threshold = *Self::get_user_data(config, &EDGE_CUTOFF_THRESHOLD_KEY)?; - let node_cutoff_threshold = *Self::get_user_data(config, &NODE_CUTOFF_THRESHOLD_KEY)?; - - let graph = discover_graph_fuzzy( - log, - unary_freq_threshold, - binary_sig_threshold, - preserve_ratio, - ratio_threshold, - utility_rate, - edge_cutoff_threshold, - node_cutoff_threshold, - ); + } + ); - context.put_concrete(GRAPH_KEY.key(), graph.to_default_graph()); + pipeline_part!(discover_fuzzy_graph, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let unary_freq_threshold = *Self::get_user_data(config, &UNARY_FREQUENCY_THRESHOLD_KEY)?; + let binary_sig_threshold = *Self::get_user_data(config, &BINARY_FREQUENCY_SIGNIFICANCE_THRESHOLD_KEY)?; + let preserve_ratio = *Self::get_user_data(config, &PRESERVE_THRESHOLD_KEY)?; + let ratio_threshold = *Self::get_user_data(config, &RATIO_THRESHOLD_KEY)?; + let utility_rate = *Self::get_user_data(config, &UTILITY_RATE_KEY)?; + let edge_cutoff_threshold = *Self::get_user_data(config, &EDGE_CUTOFF_THRESHOLD_KEY)?; + let node_cutoff_threshold = *Self::get_user_data(config, &NODE_CUTOFF_THRESHOLD_KEY)?; + + let graph = discover_graph_fuzzy( + log, + unary_freq_threshold, + binary_sig_threshold, + preserve_ratio, + ratio_threshold, + utility_rate, + edge_cutoff_threshold, + node_cutoff_threshold, + ); + + context.put_concrete(GRAPH_KEY.key(), graph.to_default_graph()); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn ensure_initial_marking() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ENSURE_INITIAL_MARKING, &|context, _, _| { - let petri_net = Self::get_user_data_mut(context, &PETRI_NET_KEY)?; - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - ensure_initial_marking(log, petri_net); + pipeline_part!(ensure_initial_marking, |context: &mut PipelineContext, _, _| { + let petri_net = Self::get_user_data_mut(context, &PETRI_NET_KEY)?; + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + ensure_initial_marking(log, petri_net); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn discover_root_sequence_graph() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_ROOT_SEQUENCE_GRAPH, &|context, _, config| { + pipeline_part!( + discover_root_sequence_graph, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; let root_sequence_kind = Self::get_user_data(config, &ROOT_SEQUENCE_KIND_KEY)?; let merge_sequences_of_events = Self::get_user_data(config, &MERGE_SEQUENCES_OF_EVENTS_KEY)?; @@ -228,6 +212,6 @@ impl PipelineParts { } Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), } - }) - } + } + ); } diff --git a/Ficus/src/rust/ficus/src/pipelines/drawing_parts.rs b/Ficus/src/rust/ficus/src/pipelines/drawing_parts.rs index 79ebda24..5f012292 100644 --- a/Ficus/src/rust/ficus/src/pipelines/drawing_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/drawing_parts.rs @@ -8,6 +8,7 @@ use crate::{ xes::{xes_event::XesEventImpl, xes_event_log::XesEventLogImpl}, }, features::analysis::patterns::activity_instances::{SubTraceKind, UNDEF_ACTIVITY_NAME}, + pipeline_part, pipelines::{ keys::context_keys::{ ATTRIBUTE_KEY, COLORS_EVENT_LOG_KEY, COLORS_HOLDER_KEY, EVENT_LOG_KEY, EVENT_NAME_KEY, REGEX_KEY, TRACE_ACTIVITIES_KEY, @@ -17,22 +18,20 @@ use crate::{ utils::{ colors::{Color, ColoredRectangle, ColorsEventLog, ColorsHolder}, references::HeapedOrOwned, - user_data::user_data::UserData, + user_data::user_data::{UserData, UserDataImpl}, }, }; impl PipelineParts { - pub(super) fn traces_diversity_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::TRACES_DIVERSITY_DIAGRAM, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let colors_holder = context.concrete_mut(COLORS_HOLDER_KEY.key()).expect("Should be initialized"); - let colors_log = Self::create_traces_diversity_colors_log(log, colors_holder, |e| HeapedOrOwned::Heaped(e.name_pointer().clone())); + pipeline_part!(traces_diversity_diagram, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let colors_holder = context.concrete_mut(COLORS_HOLDER_KEY.key()).expect("Should be initialized"); + let colors_log = Self::create_traces_diversity_colors_log(log, colors_holder, |e| HeapedOrOwned::Heaped(e.name_pointer().clone())); - context.put_concrete(COLORS_EVENT_LOG_KEY.key(), colors_log); + context.put_concrete(COLORS_EVENT_LOG_KEY.key(), colors_log); - Ok(()) - }) - } + Ok(()) + }); fn create_traces_diversity_colors_log( log: &XesEventLogImpl, @@ -66,12 +65,13 @@ impl PipelineParts { ColorsEventLog { mapping, traces } } - pub(super) fn draw_placements_of_event_by_name() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DRAW_PLACEMENT_OF_EVENT_BY_NAME, &|context, _, config| { + pipeline_part!( + draw_placement_of_event_by_name, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let event_name = Self::get_user_data(config, &EVENT_NAME_KEY)?; Self::draw_events_placement(context, &|event| event.name() == event_name) - }) - } + } + ); pub(super) fn draw_events_placement( context: &mut PipelineContext, @@ -114,16 +114,18 @@ impl PipelineParts { Ok(()) } - pub(super) fn draw_events_placements_by_regex() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DRAW_PLACEMENT_OF_EVENT_BY_REGEX, &|context, _, config| { + pipeline_part!( + draw_placement_of_event_by_regex, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let regex = Self::get_user_data(config, ®EX_KEY)?; let regex = Regex::new(regex).ok().unwrap(); Self::draw_events_placement(context, &|event| regex.is_match(event.name()).ok().unwrap()) - }) - } + } + ); - pub(super) fn draw_full_activities_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DRAW_FULL_ACTIVITIES_DIAGRAM, &|context, _, _| { + pipeline_part!( + draw_full_activities_diagram, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let traces_activities = Self::get_user_data(context, &TRACE_ACTIVITIES_KEY)?; let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let colors_holder = Self::get_user_data_mut(context, &COLORS_HOLDER_KEY)?; @@ -162,11 +164,12 @@ impl PipelineParts { context.put_concrete(COLORS_EVENT_LOG_KEY.key(), ColorsEventLog { mapping, traces }); Ok(()) - }) - } + } + ); - pub(super) fn draw_short_activities_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DRAW_SHORT_ACTIVITIES_DIAGRAM, &|context, _, _| { + pipeline_part!( + draw_short_activities_diagram, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let traces_activities = Self::get_user_data(context, &TRACE_ACTIVITIES_KEY)?; let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let colors_holder = Self::get_user_data_mut(context, &COLORS_HOLDER_KEY)?; @@ -207,11 +210,12 @@ impl PipelineParts { context.put_concrete(COLORS_EVENT_LOG_KEY.key(), ColorsEventLog { mapping, traces }); Ok(()) - }) - } + } + ); - pub(super) fn draw_traces_diversity_diagram_by_attribute() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::TRACES_DIVERSITY_DIAGRAM_BY_ATTRIBUTE, &|context, _, config| { + pipeline_part!( + traces_diversity_diagram_by_attribute, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let colors_holder = context.concrete_mut(COLORS_HOLDER_KEY.key()).expect("Should be initialized"); let attribute = Self::get_user_data(config, &ATTRIBUTE_KEY)?; @@ -229,6 +233,6 @@ impl PipelineParts { context.put_concrete(COLORS_EVENT_LOG_KEY.key(), colors_log); Ok(()) - }) - } + } + ); } diff --git a/Ficus/src/rust/ficus/src/pipelines/filtering_parts.rs b/Ficus/src/rust/ficus/src/pipelines/filtering_parts.rs index 0700dd74..23b3d23d 100644 --- a/Ficus/src/rust/ficus/src/pipelines/filtering_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/filtering_parts.rs @@ -15,6 +15,7 @@ use crate::{ filtering::{filter_log_by_name, filter_log_by_regex, remain_events_in_event_log}, split::get_traces_groups_indices, }, + pipeline_part, pipelines::{ context::PipelineContext, keys::context_keys::{EVENTS_COUNT_KEY, EVENT_LOG_KEY, EVENT_NAME_KEY, REGEX_KEY}, @@ -24,21 +25,17 @@ use crate::{ }; impl PipelineParts { - pub(super) fn filter_log_by_event_name() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::FILTER_EVENTS_BY_NAME, &|context, _, config| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let event_name = Self::get_user_data(config, &EVENT_NAME_KEY)?; - filter_log_by_name(log, &event_name); + pipeline_part!(filter_events_by_name, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + let event_name = Self::get_user_data(config, &EVENT_NAME_KEY)?; + filter_log_by_name(log, &event_name); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn filter_log_by_regex() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::FILTER_EVENTS_BY_REGEX, &|context, _, config| { - Self::filter_log_by_regex_internal(context, config, |log, regex| filter_log_by_regex(log, regex)) - }) - } + pipeline_part!(filter_events_by_regex, |context: &mut PipelineContext, _, config: &UserDataImpl| { + Self::filter_log_by_regex_internal(context, config, |log, regex| filter_log_by_regex(log, regex)) + }); fn filter_log_by_regex_internal( context: &mut PipelineContext, @@ -57,34 +54,31 @@ impl PipelineParts { } } - pub(super) fn remain_events_by_regex() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::REMAIN_EVENTS_BY_REGEX, &|context, _, config| { - Self::filter_log_by_regex_internal(context, config, |log, regex| remain_events_in_event_log(log, regex)) - }) - } + pipeline_part!(remain_events_by_regex, |context: &mut PipelineContext, _, config: &UserDataImpl| { + Self::filter_log_by_regex_internal(context, config, |log, regex| remain_events_in_event_log(log, regex)) + }); - pub(super) fn filter_log_by_variants() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::FILTER_LOG_BY_VARIANTS, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let groups_indices: HashSet = get_traces_groups_indices(log) - .into_iter() - .map(|group| *(group.first().unwrap())) - .collect(); + pipeline_part!(filter_log_by_variants, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let groups_indices: HashSet = get_traces_groups_indices(log) + .into_iter() + .map(|group| *(group.first().unwrap())) + .collect(); - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - log.filter_traces(&|_, index| !groups_indices.contains(&index)); + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + log.filter_traces(&|_, index| !groups_indices.contains(&index)); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn filter_traces_by_count() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::FILTER_TRACES_BY_EVENTS_COUNT, &|context, _, config| { + pipeline_part!( + filter_traces_by_events_count, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; let min_events_count = *Self::get_user_data(config, &EVENTS_COUNT_KEY)? as usize; log.filter_traces(&|trace, _| trace.events().len() < min_events_count); Ok(()) - }) - } + } + ); } diff --git a/Ficus/src/rust/ficus/src/pipelines/multithreading.rs b/Ficus/src/rust/ficus/src/pipelines/multithreading.rs index b04f3f04..46dd39c1 100644 --- a/Ficus/src/rust/ficus/src/pipelines/multithreading.rs +++ b/Ficus/src/rust/ficus/src/pipelines/multithreading.rs @@ -23,6 +23,7 @@ use crate::{ }, }, }, + pipeline_part, pipelines::{ context::{PipelineContext, PipelineInfrastructure}, errors::pipeline_errors::{PipelinePartExecutionError, RawPartExecutionError}, @@ -63,8 +64,9 @@ impl FromStr for FeatureCountKindDto { } impl PipelineParts { - pub(super) fn discover_log_threads_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_LOG_TIMELINE_DIAGRAM, &|context, _, config| { + pipeline_part!( + discover_log_timeline_diagram, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let thread_attribute = Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY)?; let time_attribute = Self::get_user_data(config, &TIME_ATTRIBUTE_KEY).ok(); @@ -88,8 +90,8 @@ impl PipelineParts { } Ok(()) - }) - } + } + ); fn get_control_flow_regexes(config: &SoftwareDataExtractionConfig) -> Result>, PipelinePartExecutionError> { config @@ -97,18 +99,17 @@ impl PipelineParts { .map_err(|message| PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))) } - pub(super) fn create_threads_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CREATE_THREADS_LOG, &|context, _, config| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let thread_attribute = Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY)?; - context.put_concrete(EVENT_LOG_KEY.key(), create_threads_log_by_attribute(log, thread_attribute)); + pipeline_part!(create_threads_log, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let thread_attribute = Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY)?; + context.put_concrete(EVENT_LOG_KEY.key(), create_threads_log_by_attribute(log, thread_attribute)); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn abstract_timeline_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ABSTRACT_TIMELINE_DIAGRAM, &|context, infra, config| { + pipeline_part!( + abstract_timeline_diagram, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let (thread_attribute, time_attribute) = Self::extract_thread_and_time_attribute(context)?; Self::abstract_event_groups( @@ -119,8 +120,8 @@ impl PipelineParts { thread_attribute, time_attribute, ) - }) - } + } + ); fn create_event_groups_from_timeline(context: &PipelineContext) -> Result>, PipelinePartExecutionError> { let timeline = Self::get_user_data(context, &LOG_THREADS_DIAGRAM_KEY)?; @@ -175,8 +176,9 @@ impl PipelineParts { Ok(()) } - pub fn abstract_multithreaded_events_groups() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ABSTRACT_MULTITHREADED_EVENTS_GROUPS, &|context, infra, config| { + pipeline_part!( + abstract_multithreaded_events_groups, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let thread_attribute = Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY)?.to_owned(); let time_attribute = Self::get_user_data(config, &TIME_ATTRIBUTE_KEY).ok().cloned(); let software_config = Self::get_software_data_extraction_config(context); @@ -188,8 +190,8 @@ impl PipelineParts { .map_err(|e| PipelinePartExecutionError::new_raw(e))?; Self::abstract_event_groups(groups, context, config, infra, thread_attribute, time_attribute) - }) - } + } + ); fn get_software_data_extraction_config(context: &PipelineContext) -> SoftwareDataExtractionConfig { match Self::get_user_data(context, &SOFTWARE_DATA_EXTRACTION_CONFIG_KEY) { @@ -216,8 +218,9 @@ impl PipelineParts { log } - pub(super) fn discover_traces_timeline_diagram() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_TRACES_TIMELINE_DIAGRAM, &|context, _, config| { + pipeline_part!( + discover_traces_timeline_diagram, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let time_attribute = Self::get_user_data(config, &TIME_ATTRIBUTE_KEY).ok(); let event_group_delta = Self::get_user_data(config, &TIME_DELTA_KEY).ok(); let discover_events_groups_in_each_trace = Self::get_user_data(config, &DISCOVER_EVENTS_GROUPS_IN_EACH_TRACE_KEY)?; @@ -241,11 +244,12 @@ impl PipelineParts { } Ok(()) - }) - } + } + ); - pub(super) fn prepare_software_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::PREPARE_SOFTWARE_EVENT_LOG, &|context, _, config| { + pipeline_part!( + prepare_software_event_log, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let software_data_extraction_config = Self::get_software_data_extraction_config(context); let time_attribute = Self::get_user_data(config, &TIME_ATTRIBUTE_KEY).ok(); @@ -258,45 +262,43 @@ impl PipelineParts { context.put_concrete(EVENT_LOG_KEY.key(), prepared_log); Ok(()) - }) - } + } + ); - pub(super) fn shorten_allocation_types() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SHORTEN_ALLOCATION_TYPE, &|context, _, _| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let software_data_extraction_config = Self::get_software_data_extraction_config(context); - if let Some(config) = software_data_extraction_config.allocation() { - let alloc_regex = config.event_class_regex(); - let alloc_regex = match Regex::new(alloc_regex) { - Ok(regex) => regex, - Err(err) => { - return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(format!( - "Failed to create regex from {}, error: {}", - alloc_regex, - err.to_string() - )))) - } - }; + pipeline_part!(shorten_allocation_type, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + let software_data_extraction_config = Self::get_software_data_extraction_config(context); + if let Some(config) = software_data_extraction_config.allocation() { + let alloc_regex = config.event_class_regex(); + let alloc_regex = match Regex::new(alloc_regex) { + Ok(regex) => regex, + Err(err) => { + return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(format!( + "Failed to create regex from {}, error: {}", + alloc_regex, + err.to_string() + )))) + } + }; - for trace in log.traces() { - let trace = trace.borrow_mut(); - for event in trace.events() { - if alloc_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) { - let mut event = event.borrow_mut(); - if let Some(map) = event.payload_map_mut() { - if let Some(type_name) = map.get_mut(config.info().type_name_attr().as_str()) { - let string = type_name.to_string_repr().to_string(); - *type_name = EventPayloadValue::String(Rc::new(Box::new(Self::shorten_type_or_method_name(string)))); - } + for trace in log.traces() { + let trace = trace.borrow_mut(); + for event in trace.events() { + if alloc_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) { + let mut event = event.borrow_mut(); + if let Some(map) = event.payload_map_mut() { + if let Some(type_name) = map.get_mut(config.info().type_name_attr().as_str()) { + let string = type_name.to_string_repr().to_string(); + *type_name = EventPayloadValue::String(Rc::new(Box::new(Self::shorten_type_or_method_name(string)))); } } } } } + } - Ok(()) - }) - } + Ok(()) + }); fn shorten_type_or_method_name(name: String) -> String { let mut result = String::new(); @@ -343,59 +345,57 @@ impl PipelineParts { result } - pub(super) fn shorten_methods_names() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SHORTEN_METHOD_NAMES, &|context, _, _| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + pipeline_part!(shorten_method_names, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let methods_id_factories: Vec<&dyn Fn(&String, &String, &String) -> String> = vec![ - &|_, name, _| name.to_owned(), - &|_, name, signature| name.to_owned() + signature, - &|namespace, name, _| namespace.to_string() + name, - ]; + let methods_id_factories: Vec<&dyn Fn(&String, &String, &String) -> String> = vec![ + &|_, name, _| name.to_owned(), + &|_, name, signature| name.to_owned() + signature, + &|namespace, name, _| namespace.to_string() + name, + ]; - let configs = Self::create_processed_method_extraction_configs(context); - if configs.is_empty() { - return Ok(()); - } + let configs = Self::create_processed_method_extraction_configs(context); + if configs.is_empty() { + return Ok(()); + } - for config in &configs { - for method_id_factory in &methods_id_factories { - if Self::check_if_can_use_method_id(log, config, method_id_factory) { - for trace in log.traces() { - let trace = trace.borrow_mut(); - for event in trace.events() { - let mut event = event.borrow_mut(); - let name = if let Some(payload) = event.payload_map() { - if let Some((namespace, name, signature)) = Self::extract_method_name_parts(payload, config) { - method_id_factory(&namespace, &name, &signature) - } else { - continue; - } + for config in &configs { + for method_id_factory in &methods_id_factories { + if Self::check_if_can_use_method_id(log, config, method_id_factory) { + for trace in log.traces() { + let trace = trace.borrow_mut(); + for event in trace.events() { + let mut event = event.borrow_mut(); + let name = if let Some(payload) = event.payload_map() { + if let Some((namespace, name, signature)) = Self::extract_method_name_parts(payload, config) { + method_id_factory(&namespace, &name, &signature) } else { continue; - }; + } + } else { + continue; + }; - event.set_name(name); - } + event.set_name(name); } - - return Ok(()); } + + return Ok(()); } + } - for trace in log.traces() { - let trace = trace.borrow_mut(); - for event in trace.events() { - if config.event_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) { - Self::shorten_method_name(config, &mut event.borrow_mut()); - } + for trace in log.traces() { + let trace = trace.borrow_mut(); + for event in trace.events() { + if config.event_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) { + Self::shorten_method_name(config, &mut event.borrow_mut()); } } } + } - Ok(()) - }) - } + Ok(()) + }); fn create_processed_method_extraction_configs(context: &PipelineContext) -> Vec { let software_data_extraction_config = Self::get_software_data_extraction_config(context); @@ -505,46 +505,42 @@ impl PipelineParts { true } - pub(super) fn set_methods_display_name() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::SET_METHODS_DISPLAY_NAME, &|context, _, _| { - let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; - let configs = Self::create_processed_method_extraction_configs(context); - - for trace in log.traces() { - let trace = trace.borrow(); - for event in trace.events() { - let mut display_name = None; - if let Some(payload) = event.borrow().payload_map() { - for config in &configs { - if config.event_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) { - if let Some((_, name, _)) = Self::extract_method_name_parts(payload, config) { - display_name = Some(match config.prefix.as_ref() { - None => name, - Some(prefix) => prefix.to_string() + name.as_str(), - }); - } + pipeline_part!(set_methods_display_name, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; + let configs = Self::create_processed_method_extraction_configs(context); + + for trace in log.traces() { + let trace = trace.borrow(); + for event in trace.events() { + let mut display_name = None; + if let Some(payload) = event.borrow().payload_map() { + for config in &configs { + if config.event_regex.is_match(event.borrow().name().as_str()).unwrap_or(false) { + if let Some((_, name, _)) = Self::extract_method_name_parts(payload, config) { + display_name = Some(match config.prefix.as_ref() { + None => name, + Some(prefix) => prefix.to_string() + name.as_str(), + }); } } } + } - if let Some(display_name) = display_name { - event - .borrow_mut() - .user_data_mut() - .put_concrete(DISPLAY_NAME_KEY.key(), display_name); - } + if let Some(display_name) = display_name { + event + .borrow_mut() + .user_data_mut() + .put_concrete(DISPLAY_NAME_KEY.key(), display_name); } } + } - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn remain_only_method_start_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::REMAIN_ONLY_METHOD_START_EVENTS, &|context, _, _| { - Self::remain_only_method_start_or_end_events(context, true) - }) - } + pipeline_part!(remain_only_method_start_events, |context: &mut PipelineContext, _, _| { + Self::remain_only_method_start_or_end_events(context, true) + }); fn remain_only_method_start_or_end_events( context: &PipelineContext, @@ -564,14 +560,13 @@ impl PipelineParts { Ok(()) } - pub(super) fn remain_only_method_end_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::REMAIN_ONLY_METHOD_END_EVENTS, &|context, _, _| { - Self::remain_only_method_start_or_end_events(context, false) - }) - } + pipeline_part!(remain_only_method_end_events, |context: &mut PipelineContext, _, _| { + Self::remain_only_method_start_or_end_events(context, false) + }); - pub(super) fn discover_multithreaded_dfg() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::DISCOVER_MULTITHREADED_DFG, &|context, _, config| { + pipeline_part!( + discover_multithreaded_dfg, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; let thread_attribute = Self::get_user_data(config, &THREAD_ATTRIBUTE_KEY)?; let strategy = Self::create_multithreaded_trace_parts_creation_strategy(config)?; @@ -580,8 +575,8 @@ impl PipelineParts { context.put_concrete(GRAPH_KEY.key(), dfg); Ok(()) - }) - } + } + ); fn create_multithreaded_trace_parts_creation_strategy( config: &UserDataImpl, diff --git a/Ficus/src/rust/ficus/src/pipelines/mutations_parts.rs b/Ficus/src/rust/ficus/src/pipelines/mutations_parts.rs index dcf2f34c..d161739d 100644 --- a/Ficus/src/rust/ficus/src/pipelines/mutations_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/mutations_parts.rs @@ -1,5 +1,6 @@ use crate::{ features::mutations::mutations::{add_artificial_start_end_activities, append_attributes_to_name}, + pipeline_part, pipelines::{ context::PipelineContext, errors::pipeline_errors::PipelinePartExecutionError, @@ -11,11 +12,10 @@ use crate::{ }; impl PipelineParts { - pub(super) fn add_artificial_start_end_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ADD_ARTIFICIAL_START_END_EVENTS, &|context, _, config| { - Self::create_add_start_end_events_internal(context, config, true, true) - }) - } + pipeline_part!( + add_artificial_start_end_events, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::create_add_start_end_events_internal(context, config, true, true) } + ); fn create_add_start_end_events_internal( context: &mut PipelineContext, @@ -34,26 +34,25 @@ impl PipelineParts { Ok(()) } - pub(super) fn add_artificial_start_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ADD_ARTIFICIAL_START_EVENTS, &|context, _, config| { - Self::create_add_start_end_events_internal(context, config, true, false) - }) - } + pipeline_part!( + add_artificial_start_events, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::create_add_start_end_events_internal(context, config, true, false) } + ); - pub(super) fn add_artificial_end_events() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ADD_ARTIFICIAL_END_EVENTS, &|context, _, config| { - Self::create_add_start_end_events_internal(context, config, false, true) - }) - } + pipeline_part!( + add_artificial_end_events, + |context: &mut PipelineContext, _, config: &UserDataImpl| { Self::create_add_start_end_events_internal(context, config, false, true) } + ); - pub(super) fn append_attributes_to_name() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::APPEND_ATTRIBUTES_TO_NAME, &|context, _, config| { + pipeline_part!( + append_attributes_to_name, + |context: &mut PipelineContext, _, config: &UserDataImpl| { let log = Self::get_user_data_mut(context, &EVENT_LOG_KEY)?; let attributes = Self::get_user_data(config, &ATTRIBUTES_KEY)?; append_attributes_to_name(log, attributes); Ok(()) - }) - } + } + ); } diff --git a/Ficus/src/rust/ficus/src/pipelines/parts_names.rs b/Ficus/src/rust/ficus/src/pipelines/parts_names.rs index 3f270442..20de137f 100644 --- a/Ficus/src/rust/ficus/src/pipelines/parts_names.rs +++ b/Ficus/src/rust/ficus/src/pipelines/parts_names.rs @@ -27,7 +27,7 @@ impl PipelineParts { pub const GET_NAMES_EVENT_LOG: &'static str = "GetNamesEventLog"; pub const GET_HASHES_EVENT_LOG: &'static str = "GetHashesEventLog"; pub const USE_NAMES_EVENT_LOG: &'static str = "UseNamesEventLog"; - pub const DISCOVER_ACTIVITIES_FOR_SEVERAL_LEVEL: &'static str = "DiscoverActivitiesForSeveralLevels"; + pub const DISCOVER_ACTIVITIES_FOR_SEVERAL_LEVELS: &'static str = "DiscoverActivitiesForSeveralLevels"; pub const DISCOVER_ACTIVITIES_IN_UNATTACHED_SUBTRACES: &'static str = "DiscoverActivitiesInUnattachedSubTraces"; pub const DISCOVER_ACTIVITIES_UNTIL_NO_MORE: &'static str = "DiscoverActivitiesUntilNoMore"; pub const EXECUTE_WITH_EACH_ACTIVITY_LOG: &'static str = "ExecuteWithEachActivityLog"; diff --git a/Ficus/src/rust/ficus/src/pipelines/pipeline_parts.rs b/Ficus/src/rust/ficus/src/pipelines/pipeline_parts.rs index 54ee16d9..b917a723 100644 --- a/Ficus/src/rust/ficus/src/pipelines/pipeline_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/pipeline_parts.rs @@ -41,6 +41,19 @@ impl PipelineParts { unsafe impl Sync for PipelineParts {} unsafe impl Send for PipelineParts {} +#[macro_export] +macro_rules! pipeline_part { + ($name:ident, $body:expr) => { + paste::item! { + pub(super) fn $name () -> (String, PipelinePartFactory) { + Self::create_pipeline_part(Self::[<$name:upper>], &|context, infra, config| { + $body(context, infra, config) + }) + } + } + }; +} + impl PipelineParts { pub fn new() -> Self { let parts = vec![ @@ -54,23 +67,23 @@ impl PipelineParts { Self::discover_activities(), Self::discover_activities_instances(), Self::create_log_from_activities(), - Self::filter_log_by_event_name(), - Self::filter_log_by_regex(), + Self::filter_events_by_name(), + Self::filter_events_by_regex(), Self::remain_events_by_regex(), Self::filter_log_by_variants(), - Self::draw_placements_of_event_by_name(), - Self::draw_events_placements_by_regex(), + Self::draw_placement_of_event_by_name(), + Self::draw_placement_of_event_by_regex(), Self::draw_full_activities_diagram(), Self::draw_short_activities_diagram(), Self::get_event_log_info(), - Self::clear_activities_related_stuff(), - Self::get_number_of_underlying_events(), - Self::filter_traces_by_count(), + Self::clear_activities(), + Self::get_underlying_events_count(), + Self::filter_traces_by_events_count(), Self::traces_diversity_diagram(), Self::get_names_event_log(), Self::get_hashes_event_log(), Self::use_names_event_log(), - Self::discover_activities_instances_for_several_levels(), + Self::discover_activities_for_several_levels(), Self::discover_activities_in_unattached_subtraces(), Self::discover_activities_until_no_more(), Self::execute_with_each_activity_log(), @@ -85,45 +98,45 @@ impl PipelineParts { Self::discover_petri_net_alpha_plus(), Self::discover_petri_net_alpha_plus_plus(), Self::discover_petri_net_alpha_plus_plus_nfc(), - Self::discover_directly_follows_graph(), - Self::discover_petri_net_heuristic_miner(), + Self::discover_dfg(), + Self::discover_petri_net_heuristic(), Self::discover_fuzzy_graph(), Self::annotate_petri_net_count(), Self::annotate_petri_net_frequency(), Self::annotate_petri_net_trace_frequency(), Self::ensure_initial_marking(), Self::read_log_from_bxes(), - Self::clusterize_activities_from_traces_k_means(), - Self::clusterize_activities_from_traces_k_means_grid_search(), + Self::clusterize_activities_from_traces_kmeans(), + Self::clusterize_activities_from_traces_kmeans_grid_search(), Self::clusterize_activities_from_traces_dbscan(), Self::create_traces_activities_dataset(), Self::write_log_to_bxes(), Self::clusterize_log_traces(), Self::serialize_activities_logs(), - Self::read_xes_from_bytes(), - Self::read_bxes_from_bytes(), - Self::write_bxes_to_bytes(), - Self::write_xes_to_bytes(), + Self::read_xes_log_from_bytes(), + Self::read_bxes_log_from_bytes(), + Self::write_bxes_log_to_bytes(), + Self::write_xes_log_to_bytes(), Self::reverse_hierarchy_indices(), Self::discover_cases(), - Self::annotate_graph_with_time_performance(), - Self::draw_traces_diversity_diagram_by_attribute(), - Self::discover_directly_follows_graph_by_attribute(), + Self::annotate_graph_with_time(), + Self::traces_diversity_diagram_by_attribute(), + Self::discover_dfg_by_attribute(), Self::append_attributes_to_name(), Self::merge_xes_logs_from_paths(), - Self::discover_directly_follows_graph_stream(), + Self::discover_dfg_stream(), Self::discover_petri_net_alpha_stream(), - Self::discover_log_threads_diagram(), + Self::discover_log_timeline_diagram(), Self::create_threads_log(), Self::abstract_timeline_diagram(), - Self::clusterize_log_by_traces_k_means_grid_search(), + Self::clusterize_log_traces_k_means_grid_search(), Self::clusterize_log_traces_dbscan_grid_search(), Self::discover_root_sequence_graph(), Self::discover_loops_strict(), Self::discover_traces_timeline_diagram(), - Self::prepare_software_log(), - Self::shorten_allocation_types(), - Self::shorten_methods_names(), + Self::prepare_software_event_log(), + Self::shorten_allocation_type(), + Self::shorten_method_names(), Self::set_methods_display_name(), Self::remain_only_method_start_events(), Self::remain_only_method_end_events(), diff --git a/Ficus/src/rust/ficus/src/pipelines/util_parts.rs b/Ficus/src/rust/ficus/src/pipelines/util_parts.rs index 14775813..dcfeab4f 100644 --- a/Ficus/src/rust/ficus/src/pipelines/util_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/util_parts.rs @@ -16,7 +16,9 @@ use crate::{ xes::{xes_event::XesEventImpl, xes_event_log::XesEventLogImpl, xes_trace::XesTraceImpl}, }, features::analysis::log_info::{event_log_info::OfflineEventLogInfo, log_info_creation_dto::EventLogInfoCreationDto}, + pipeline_part, pipelines::{ + context::{PipelineContext, PipelineInfrastructure}, errors::pipeline_errors::PipelinePartExecutionError, keys::context_keys::{ EVENT_CLASS_REGEX_KEY, EVENT_LOG_INFO_KEY, EVENT_LOG_KEY, GRAPHS_KEY, GRAPH_KEY, HASHES_EVENT_LOG_KEY, NAMES_EVENT_LOG_KEY, @@ -42,121 +44,106 @@ impl PipelineParts { } } - pub(super) fn get_event_log_info() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::GET_EVENT_LOG_INFO, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let log_info = OfflineEventLogInfo::create_from(EventLogInfoCreationDto::default(log)); - context.put_concrete(EVENT_LOG_INFO_KEY.key(), log_info); + pipeline_part!(get_event_log_info, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let log_info = OfflineEventLogInfo::create_from(EventLogInfoCreationDto::default(log)); + context.put_concrete(EVENT_LOG_INFO_KEY.key(), log_info); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn get_hashes_event_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::GET_HASHES_EVENT_LOG, &|context, _, config| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let hashes_event_log = Self::create_hashed_event_log(config, log); + pipeline_part!(get_hashes_event_log, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let hashes_event_log = Self::create_hashed_event_log(config, log); - context.put_concrete(HASHES_EVENT_LOG_KEY.key(), hashes_event_log); - - Ok(()) - }) - } + context.put_concrete(HASHES_EVENT_LOG_KEY.key(), hashes_event_log); - pub(super) fn get_names_event_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::GET_NAMES_EVENT_LOG, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + Ok(()) + }); - let mut result = vec![]; - for trace in log.traces() { - let mut vec = vec![]; - for event in trace.borrow().events() { - vec.push(event.borrow().name().to_string()); - } + pipeline_part!(get_names_event_log, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - result.push(vec); + let mut result = vec![]; + for trace in log.traces() { + let mut vec = vec![]; + for event in trace.borrow().events() { + vec.push(event.borrow().name().to_string()); } - context.put_concrete(NAMES_EVENT_LOG_KEY.key(), result); + result.push(vec); + } - Ok(()) - }) - } + context.put_concrete(NAMES_EVENT_LOG_KEY.key(), result); - pub(super) fn use_names_event_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::USE_NAMES_EVENT_LOG, &|context, _, _| { - let names_log = Self::get_user_data(context, &NAMES_EVENT_LOG_KEY)?; - let mut log = XesEventLogImpl::empty(); - for names_trace in names_log { - let mut trace = XesTraceImpl::empty(); - let mut date = DateTime::::MIN_UTC; - - for name in names_trace { - let event = XesEventImpl::new(name.clone(), date.clone()); - trace.push(Rc::new(RefCell::new(event))); - date = date + Duration::seconds(1); - } - - log.push(Rc::new(RefCell::new(trace))); + Ok(()) + }); + + pipeline_part!(use_names_event_log, |context: &mut PipelineContext, _, _| { + let names_log = Self::get_user_data(context, &NAMES_EVENT_LOG_KEY)?; + let mut log = XesEventLogImpl::empty(); + for names_trace in names_log { + let mut trace = XesTraceImpl::empty(); + let mut date = DateTime::::MIN_UTC; + + for name in names_trace { + let event = XesEventImpl::new(name.clone(), date.clone()); + trace.push(Rc::new(RefCell::new(event))); + date = date + Duration::seconds(1); } - context.put_concrete::(EVENT_LOG_KEY.key(), log); + log.push(Rc::new(RefCell::new(trace))); + } - Ok(()) - }) - } + context.put_concrete::(EVENT_LOG_KEY.key(), log); + + Ok(()) + }); - pub(super) fn execute_frontend_pipeline() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::EXECUTE_FRONTEND_PIPELINE, &|context, infra, config| { + pipeline_part!( + execute_frontend_pipeline, + |context: &mut PipelineContext, infra: &PipelineInfrastructure, config: &UserDataImpl| { let pipeline = Self::get_user_data(config, &PIPELINE_KEY)?; pipeline.execute(context, infra)?; Ok(()) - }) - } + } + ); - pub(super) fn merge_graphs() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::MERGE_GRAPHS, &|context, _, _| { - let graphs = Self::get_user_data(context, &GRAPHS_KEY)?; + pipeline_part!(merge_graphs, |context: &mut PipelineContext, _, _| { + let graphs = Self::get_user_data(context, &GRAPHS_KEY)?; - let graph = merge_graphs(graphs).map_err(|e| PipelinePartExecutionError::new_raw(e.to_string()))?; - context.put_concrete(GRAPH_KEY.key(), graph); + let graph = merge_graphs(graphs).map_err(|e| PipelinePartExecutionError::new_raw(e.to_string()))?; + context.put_concrete(GRAPH_KEY.key(), graph); - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn add_graph_to_graphs() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::ADD_GRAPH_TO_GRAPHS, &|context, _, _| { - let graph = Self::get_user_data(context, &GRAPH_KEY)?.clone(); + pipeline_part!(add_graph_to_graphs, |context: &mut PipelineContext, _, _| { + let graph = Self::get_user_data(context, &GRAPH_KEY)?.clone(); - match Self::get_user_data_mut(context, &GRAPHS_KEY).ok() { - None => context.put_concrete(GRAPHS_KEY.key(), vec![graph]), - Some(graphs) => graphs.push(graph), - } + match Self::get_user_data_mut(context, &GRAPHS_KEY).ok() { + None => context.put_concrete(GRAPHS_KEY.key(), vec![graph]), + Some(graphs) => graphs.push(graph), + } - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn clear_graphs() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::CLEAR_GRAPHS, &|context, _, _| { - if let Some(graphs) = Self::get_user_data_mut(context, &GRAPHS_KEY).ok() { - graphs.clear(); - } + pipeline_part!(clear_graphs, |context: &mut PipelineContext, _, _| { + if let Some(graphs) = Self::get_user_data_mut(context, &GRAPHS_KEY).ok() { + graphs.clear(); + } - Ok(()) - }) - } + Ok(()) + }); - pub(super) fn terminate_if_empty_log() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::TERMINATE_IF_EMPTY_LOG, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - if log.traces().iter().map(|t| t.borrow().events().len()).sum::() == 0 { - return Err(PipelinePartExecutionError::new_raw("Empty log".to_string())); - } + pipeline_part!(terminate_if_empty_log, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + if log.traces().iter().map(|t| t.borrow().events().len()).sum::() == 0 { + return Err(PipelinePartExecutionError::new_raw("Empty log".to_string())); + } - Ok(()) - }) - } + Ok(()) + }); } diff --git a/Ficus/src/rust/ficus/src/pipelines/xes_parts.rs b/Ficus/src/rust/ficus/src/pipelines/xes_parts.rs index c2fc3434..3a7b0afc 100644 --- a/Ficus/src/rust/ficus/src/pipelines/xes_parts.rs +++ b/Ficus/src/rust/ficus/src/pipelines/xes_parts.rs @@ -14,149 +14,132 @@ use crate::{ writer::xes_event_log_writer::{write_xes_log, write_xes_log_to_bytes}, }, }, + pipeline_part, pipelines::{ - context::PipelineContext, + context::{PipelineContext, PipelineInfrastructure}, keys::context_keys::{BYTES_KEY, EVENT_LOG_KEY, PATHS_KEY, PATH_KEY, SYSTEM_METADATA_KEY}, pipeline_parts::PipelineParts, }, - utils::user_data::user_data::UserData, + utils::user_data::user_data::{UserData, UserDataImpl}, }; impl PipelineParts { - pub(super) fn write_log_to_xes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::WRITE_LOG_TO_XES, &|context, _, config| { - let path = Self::get_user_data(config, &PATH_KEY)?; - match write_xes_log(&context.concrete(EVENT_LOG_KEY.key()).unwrap(), path) { - Ok(()) => Ok(()), - Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + pipeline_part!(write_log_to_xes, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let path = Self::get_user_data(config, &PATH_KEY)?; + match write_xes_log(&context.concrete(EVENT_LOG_KEY.key()).unwrap(), path) { + Ok(()) => Ok(()), + Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + } + }); + + pipeline_part!(read_log_from_xes, |context: &mut PipelineContext, _, _| { + let path = Self::get_user_data(context, &PATH_KEY)?; + + let log = read_event_log(path); + if log.is_none() { + let message = format!("Failed to read event log from {}", path.as_str()); + return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))); + } + + context.put_concrete(EVENT_LOG_KEY.key(), log.unwrap()); + Ok(()) + }); + + pipeline_part!(read_log_from_bxes, |context: &mut PipelineContext, _, _| { + let path = Self::get_user_data(context, &PATH_KEY)?; + + match read_bxes_into_xes_log(path) { + Ok(result) => { + Self::put_read_result_to_context(context, result); + Ok(()) } - }) - } - - pub(super) fn read_log_from_xes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::READ_LOG_FROM_XES, &|context, _, _| { - let path = Self::get_user_data(context, &PATH_KEY)?; - - let log = read_event_log(path); - if log.is_none() { - let message = format!("Failed to read event log from {}", path.as_str()); - return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))); + Err(err) => { + let message = format!("Failed to read event log from {}, error: {}", path.as_str(), err.to_string()); + Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))) } - - context.put_concrete(EVENT_LOG_KEY.key(), log.unwrap()); - Ok(()) - }) - } - - pub(super) fn read_log_from_bxes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::READ_LOG_FROM_BXES, &|context, _, _| { - let path = Self::get_user_data(context, &PATH_KEY)?; - - match read_bxes_into_xes_log(path) { - Ok(result) => { - Self::put_read_result_to_context(context, result); - Ok(()) - } - Err(err) => { - let message = format!("Failed to read event log from {}, error: {}", path.as_str(), err.to_string()); - Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))) - } - } - }) - } + } + }); fn put_read_result_to_context(context: &mut PipelineContext, result: BxesToXesConversionResult) { context.put_concrete(EVENT_LOG_KEY.key(), result.xes_log); context.put_concrete(SYSTEM_METADATA_KEY.key(), result.system_metadata); } - pub(super) fn write_log_to_bxes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::WRITE_LOG_TO_BXES, &|context, _, config| { - let path = Self::get_user_data(config, &PATH_KEY)?; - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let system_metadata = match Self::get_user_data(context, &SYSTEM_METADATA_KEY) { - Ok(metadata) => Some(metadata), - Err(_) => None, - }; - - match write_event_log_to_bxes(log, system_metadata, path) { - Ok(_) => Ok(()), - Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + pipeline_part!(write_log_to_bxes, |context: &mut PipelineContext, _, config: &UserDataImpl| { + let path = Self::get_user_data(config, &PATH_KEY)?; + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let system_metadata = match Self::get_user_data(context, &SYSTEM_METADATA_KEY) { + Ok(metadata) => Some(metadata), + Err(_) => None, + }; + + match write_event_log_to_bxes(log, system_metadata, path) { + Ok(_) => Ok(()), + Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + } + }); + + pipeline_part!(read_xes_log_from_bytes, |context: &mut PipelineContext, _, _| { + let bytes = Self::get_user_data(context, &BYTES_KEY)?; + match read_event_log_from_bytes(bytes) { + Some(log) => { + context.put_concrete(EVENT_LOG_KEY.key(), log); + Ok(()) } - }) - } - - pub(super) fn read_xes_from_bytes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::READ_XES_LOG_FROM_BYTES, &|context, _, _| { - let bytes = Self::get_user_data(context, &BYTES_KEY)?; - match read_event_log_from_bytes(bytes) { - Some(log) => { - context.put_concrete(EVENT_LOG_KEY.key(), log); - Ok(()) - } - None => { - let message = "Failed to read event log from bytes array".to_string(); - return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))); - } + None => { + let message = "Failed to read event log from bytes array".to_string(); + return Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))); } - }) - } - - pub(super) fn read_bxes_from_bytes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::READ_BXES_LOG_FROM_BYTES, &|context, _, _| { - let bytes = Self::get_user_data(context, &BYTES_KEY)?; - match read_bxes_into_xes_log_from_bytes(bytes) { - Ok(read_result) => { - Self::put_read_result_to_context(context, read_result); - Ok(()) - } - Err(err) => { - let message = format!("Failed to read event log from bytes: {}", err.to_string()); - Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))) - } + } + }); + + pipeline_part!(read_bxes_log_from_bytes, |context: &mut PipelineContext, _, _| { + let bytes = Self::get_user_data(context, &BYTES_KEY)?; + match read_bxes_into_xes_log_from_bytes(bytes) { + Ok(read_result) => { + Self::put_read_result_to_context(context, read_result); + Ok(()) } - }) - } - - pub(super) fn write_bxes_to_bytes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::WRITE_BXES_LOG_TO_BYTES, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - let system_metadata = match Self::get_user_data(context, &SYSTEM_METADATA_KEY) { - Ok(metadata) => Some(metadata), - Err(_) => None, - }; - - match write_event_log_to_bxes_bytes(log, system_metadata) { - Ok(bytes) => { - context.put_concrete::>(BYTES_KEY.key(), bytes); - Ok(()) - } - Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + Err(err) => { + let message = format!("Failed to read event log from bytes: {}", err.to_string()); + Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(message))) } - }) - } - - pub(super) fn write_xes_to_bytes() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::WRITE_XES_LOG_TO_BYTES, &|context, _, _| { - let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; - match write_xes_log_to_bytes(log) { - Ok(bytes) => { - context.put_concrete::>(&BYTES_KEY.key(), bytes); - Ok(()) - } - Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + } + }); + + pipeline_part!(write_bxes_log_to_bytes, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + let system_metadata = match Self::get_user_data(context, &SYSTEM_METADATA_KEY) { + Ok(metadata) => Some(metadata), + Err(_) => None, + }; + + match write_event_log_to_bxes_bytes(log, system_metadata) { + Ok(bytes) => { + context.put_concrete::>(BYTES_KEY.key(), bytes); + Ok(()) } - }) - } + Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + } + }); + + pipeline_part!(write_xes_log_to_bytes, |context: &mut PipelineContext, _, _| { + let log = Self::get_user_data(context, &EVENT_LOG_KEY)?; + match write_xes_log_to_bytes(log) { + Ok(bytes) => { + context.put_concrete::>(&BYTES_KEY.key(), bytes); + Ok(()) + } + Err(err) => Err(PipelinePartExecutionError::Raw(RawPartExecutionError::new(err.to_string()))), + } + }); - pub(super) fn merge_xes_logs_from_paths() -> (String, PipelinePartFactory) { - Self::create_pipeline_part(Self::MERGE_XES_LOGS_FROM_PATHS, &|context, _, _| { - let paths = Self::get_user_data(context, &PATHS_KEY)?; - let log = merge_xes_logs(paths); + pipeline_part!(merge_xes_logs_from_paths, |context: &mut PipelineContext, _, _| { + let paths = Self::get_user_data(context, &PATHS_KEY)?; + let log = merge_xes_logs(paths); - context.put_concrete(EVENT_LOG_KEY.key(), log); + context.put_concrete(EVENT_LOG_KEY.key(), log); - Ok(()) - }) - } + Ok(()) + }); } diff --git a/Ficus/src/rust/ficus_backend/src/main.rs b/Ficus/src/rust/ficus_backend/src/main.rs index 39ba5c94..693a12f3 100644 --- a/Ficus/src/rust/ficus_backend/src/main.rs +++ b/Ficus/src/rust/ficus_backend/src/main.rs @@ -1,8 +1,14 @@ -use ficus::ficus_proto::grpc_context_values_service_server::GrpcContextValuesServiceServer; -use ficus::ficus_proto::grpc_kafka_service_server::GrpcKafkaServiceServer; -use ficus::grpc::context_values_service::{ContextValueService, GrpcContextValueService}; -use ficus::grpc::kafka::grpc_kafka_service::GrpcKafkaServiceImpl; -use ficus::{ficus_proto::grpc_backend_service_server::GrpcBackendServiceServer, grpc::backend_service::FicusService}; +use ficus::{ + ficus_proto::{ + grpc_backend_service_server::GrpcBackendServiceServer, grpc_context_values_service_server::GrpcContextValuesServiceServer, + grpc_kafka_service_server::GrpcKafkaServiceServer, + }, + grpc::{ + backend_service::FicusService, + context_values_service::{ContextValueService, GrpcContextValueService}, + kafka::grpc_kafka_service::GrpcKafkaServiceImpl, + }, +}; use log::{info, LevelFilter}; use std::sync::Arc; use tonic::transport::Server;