public PMViewer(Field field, ModernWindow window, bool isDiff = false, string headingtext = "") { InitializeComponent(); CurrentField = field; _associatedWindow = window; _associatedWindow.Title = "Model View"; ShowProcessModelInCanvas(); _associatedWindow.PreviewKeyDown += HandleShortcuts; _associatedWindow.PreviewMouseWheel += Zoom; HeadingText.Text = headingtext != "" ? headingtext : field.Infotext; //IsDiff = isDiff; //if (IsDiff) //{ // CloseButton1.Visibility = Visibility.Visible; // ShowLegend(); //} //else //{ // CloseButton1.Visibility = Visibility.Hidden; //} }
/// <summary> /// Constructor for the HeuristicMiner, initializes values and sets the "field" that will be mined. /// </summary> /// <param name="field">A field from the DataSelection</param> public HeuristicMiner(Field field) { _field = field; _finalPetriNet = new PetriNet(field.Infotext); _listOfSubPetriNets = new List<PetriNet>(); _openParallelismCount = new Stack<Parallelism>(); _listOfNodes = new HashSet<double>(); }
//public bool IsDiff; public PMViewer() { InitializeComponent(); CurrentField = Viewer.CurrentField; ShowProcessModelInCanvas(); HeadingText.Text = CurrentField.Infotext; PreviewKeyDown += HandleShortcuts; PreviewMouseWheel += Zoom; }
/// <summary> /// Conformance Check between the eventlog and generated process model. /// The criticized transitions are shown in the process model. /// </summary> /// <autor>Andrej Albrecht</autor> public void DrawConformanceModelInCanvas(Field field, Canvas canvas) { try { // Create Footprints ComparingFootprint footPrintEventlog = ComparingFootprintAlgorithm.CreateFootprint(field.EventLog); ComparingFootprint footPrintPetrinet = ComparingFootprintAlgorithm.CreateFootprint((PetriNet)field.ProcessModel); ComparingFootprintResultMatrix resultFootprint = new ComparingFootprintResultMatrix(footPrintEventlog, footPrintPetrinet); // Calculate Fitness double fitnessComparingFootprint = ComparingFootprintAlgorithm.CalculateFitness(resultFootprint.GetNumberOfDifferences(), resultFootprint.GetNumberOfOpportunities()); FitnessComparingFootprints.Content = "Fitness Comparing Footprints: " + Math.Round(fitnessComparingFootprint * 100, 2) + " %"; // Prepare Canvas & draw model RemoveListenerFromCanvas(canvas); canvas.Children.Clear(); VisualizationHelpers.GetOrCreatePetriNetVisualization(field, canvas); AddListenertoTransitions(canvas); // Color the transitions in List<String> listOfGreenTransitions = new List<String>(); List<String> listOfRedTransitions = new List<String>(); List<List<String>> listOfLinesToBeRemoved = new List<List<String>>(); int row = 0; foreach (String rowHeaderName in resultFootprint.HeaderWithEventNames) { int column = 0; foreach (String columnHeaderName in resultFootprint.HeaderWithEventNames) { if (resultFootprint.ResultMatrix[row, column].Equals(ResultCellType.NoDifferences) && rowHeaderName.Equals(columnHeaderName)) listOfGreenTransitions.Add(rowHeaderName); else if (resultFootprint.ResultMatrix[row, column].Equals(ResultCellType.NothingAndRight)) listOfLinesToBeRemoved.Add(new List<String> { rowHeaderName, columnHeaderName }); // else if (ResultFootprint.ResultMatrix[Row, Column].Equals(ResultCellType.RightAndNothing)) // Model enhacement: here you can fill a list of lines that are must to be add to the petrinet // example: listOfLinesToAddTo.Add(new TransitionCombination(yHeaderName, xHeaderName)); else if (rowHeaderName.Equals(columnHeaderName)) listOfRedTransitions.Add(rowHeaderName); column++; } row++; } SetColorInCanvas(listOfGreenTransitions, Brushes.Green, canvas); SetColorInCanvas(listOfRedTransitions, Brushes.Red, canvas); SetColorOnLinesToBeRemoved(listOfLinesToBeRemoved, canvas, (PetriNet)field.ProcessModel); } catch (Exception Ex) { ErrorHandling.ReportErrorToUser("Error: " + Ex.Message + Ex.StackTrace); } }
/// <summary> /// Initialize the InductiveMiner instance. /// </summary> /// <param name="field">Corresponding field</param> /// <author>Krystian Zielonka, Thomas Meents, Bernd Nottbeck</author> public InductiveMiner(Field field) { _field = field; DirectRowList = new List<InductiveMinerRow>(); EventDictionary = new Dictionary<Event, InductiveMinerGraphNode>(); IMPetriNet = new PetriNet(_field.Infotext); StartEvent = new Event("StartEvent"); EndEvent = new Event("EndEvent"); EventuallyRowList = new List<InductiveMinerRow>(); }
public void CalculateStandardDeviationTest() { var field = new Field { EventLog = EventLogExample.ThreeCaseEventLog() }; var miner = new HeuristicMiner(field); var values = new List<double> { 0.2, 0.4, 0.6, 0.8 }; var actual = miner.CalculateStandardDeviation(values); Assert.AreEqual(0.258, actual); }
/// <summary> /// Goes through the inductive miner algorithm /// </summary> /// <param name="field">A field from the data selection</param> /// <returns>A PetriNet as a ProcessModel</returns> public static ProcessModel Mine(Field field) { if (field == null) throw new ArgumentNullException("field", "The field parameter was null"); TraceFrequency(field); DetectAllConnections(); DivideAndConquer(); return AlphaMiner.Mine(field); }
public void AlphaMinerDetectActivitySetTest() { Field field = new Field { EventLog = GenerateTestLog() }; AlphaMiner alphaMiner = new AlphaMiner(field); PrivateObject priObj = new PrivateObject(alphaMiner); priObj.Invoke("DetectActivitiySet"); HashSet<String> listOfActivities = (HashSet<String>)priObj.GetField("_listOfActivities"); Assert.IsNotNull(listOfActivities); }
public void CreateAdjacencyMatrixTest() { var field = new Field { EventLog = EventLogExample.ThreeCaseEventLog() }; var miner = new HeuristicMiner(field); var actual = miner.CreateAdjacencyMatrix(field); var expected = new[,] { { 0.0, 0.5, 0.5, 0.0, 0.5 }, { -0.5, 0.0, 0.0, 0.5, 0.0 }, { -0.5, 0.0, 0.0, 0.5, 0.0 }, { 0.0, -0.5, -0.5, 0.0, -0.5 }, { -0.5, 0.0, 0.0, 0.5, 0.0 } }; for (var i = 0; i < 5; i++) for (var j = 0; j < 5; j++) Assert.AreEqual(expected[i, j], actual[i, j]); }
/// <summary> /// This method adds the current field to the AND-List, if one of the condition is fulfilled. /// </summary> /// <param name="_listOfSelectedOptions">List with selected options.</param> /// <param name="_ListOfFieldsWithAND">Contains the fields which fulfill the conditions.</param> /// <param name="IsLoopExisting">Boolean if loops are in the current field.</param> /// <param name="IsParallelismExisting">Boolean if parallelism are in the current field.</param> /// <param name="IsSelectedEventExisting">Boolean if the selected events are in the current field.</param> /// <param name="IsProcessmodelWithNumberOfEventsExisting"></param> /// <param name="CurrentField">The current field contains a net.</param> /// <author>Christopher Licht, Bernhard Bruns</author> private static void AddCurrentFieldToANDListIfConditionsFulfilled(HashSet<String> _listOfSelectedOptions, HashSet<Field> _ListOfFieldsWithAND, Boolean IsLoopExisting, Boolean IsParallelismExisting, Boolean IsSelectedEventExisting, Boolean IsProcessmodelWithNumberOfEventsExisting, Field CurrentField) { if ((_listOfSelectedOptions.Contains("Loop") && IsLoopExisting) && (_listOfSelectedOptions.Contains("Events") && IsSelectedEventExisting) && (IsParallelismExisting == false)) _ListOfFieldsWithAND.Add(CurrentField); else if ((_listOfSelectedOptions.Contains("Loop") && IsLoopExisting) && (_listOfSelectedOptions.Contains("Parallelism") && IsParallelismExisting) && IsSelectedEventExisting == false) _ListOfFieldsWithAND.Add(CurrentField); else if ((_listOfSelectedOptions.Contains("Parallelism") && IsParallelismExisting) && (_listOfSelectedOptions.Contains("Events") && IsSelectedEventExisting) && IsLoopExisting == false) _ListOfFieldsWithAND.Add(CurrentField); else if ((_listOfSelectedOptions.Contains("Parallelism") && IsParallelismExisting) && (_listOfSelectedOptions.Contains("Events") && IsSelectedEventExisting) && (_listOfSelectedOptions.Contains("Loop") && IsLoopExisting)) _ListOfFieldsWithAND.Add(CurrentField); else if (_listOfSelectedOptions.Contains("Min. Number of Events") && IsProcessmodelWithNumberOfEventsExisting) _ListOfFieldsWithAND.Add(CurrentField); }
public Viewer(Field field, bool isDiff = false, string headingtext = "") { if (field.ProcessModel == null) throw new ArgumentNullException("field", @"No processmodel can be found for this field"); InitializeComponent(); CurrentField = field; PreviewKeyDown += HandleShortcuts; //Topmost = false; }
/// <summary> /// Returns the Visualization of the field, creates on if it does not already exist. /// </summary> /// <param name="field"></param> /// <param name="canvas"></param> /// <param name="dragAndDrop"></param> /// <param name="forceRedraw"></param> /// <returns></returns> /// <author>Jannik Arndt</author> public static Canvas GetOrCreatePetriNetVisualization(Field field, Canvas canvas, bool dragAndDrop = true, bool forceRedraw = false) { PetriNetVisualizer petriNetVisualizer = new PetriNetVisualizer(); try { return petriNetVisualizer.DrawPetriNet((PetriNet)field.ProcessModel, canvas, dragAndDrop, forceRedraw); } catch (KeyNotFoundException) { ErrorHandling.ReportErrorToUser("This process model cannot be viewed, probably because a loop was not properly marked."); } return null; }
public AlphaMiner(Field field) { _field = field; _petriNet = new PetriNet(field.Infotext); _listOfActivities = new HashSet<String>(); _listOfStartActivities = new HashSet<String>(); _listOfEndActivities = new HashSet<String>(); _listOfAlphaPlaces = new List<AlphaMinerPlaces>(); _listOfAllPairs = new Dictionary<String, Tuple<HashSet<String>, HashSet<String>>>(); _listOfLoopsWithTheLengthOfTwo = new Dictionary<String, HashSet<String>>(); _listOfAllParallelPairs = new Dictionary<String, HashSet<String>>(); _listOfAllDoubleActivities = new HashSet<String>(); _listOfActivitiesInCase = new List<List<String>>(); }
public static IMiner CreateMiner(String miner, Field field) { switch (miner) { case "Alpha Miner": return new AlphaMiner(field); case "Heuristic Miner": return new HeuristicMiner(field); case "Inductive Miner": if (MinerSettings.ListOfMinerSettings["InductiveMiner"].ToString().Equals("InductiveMiner")) return new InductiveMiner(field); return new InductiveMinerInfrequent(field); default: throw new ArgumentException("Invalid miner", "miner"); } }
public void FindFirstCommonSuccessorTest() { var eventLog = EventLogExample.ComplexEventLogVanDerAalst(); var field = new Field { EventLog = eventLog }; var miner = new HeuristicMiner(field); var event1 = eventLog.Cases[0].EventList[0]; var event2 = eventLog.Cases[0].EventList[1]; var event3 = eventLog.Cases[0].EventList[2]; var eventNode1 = new EventNode(event1, 0.8, new List<EventNode> { new EventNode(event2, 0.8, new List<EventNode> { new EventNode(event3, 0.8) }) }); var eventNode2 = new EventNode(event1, 0.8, new List<EventNode> { new EventNode(event2, 0.8, new List<EventNode> { new EventNode(event3, 0.8) }) }); var actual = miner.FindFirstCommonSuccessor(new List<EventNode> { eventNode1, eventNode2 }); Assert.AreEqual("C", actual); }
public void CreateDependencyGraphTest() { var field = new Field { EventLog = EventLogExample.ThreeCaseEventLog() }; var miner = new HeuristicMiner(field); var event1 = new Event("A"); var event2 = new Event("B"); var event3 = new Event("C"); var eventList = new List<Event> { event1, event2, event3 }; var matrix = new[,] { { 0.0, 0.8, 0.0 }, { 0.0, 0.0, 0.8 }, { 0.0, 0.0, 0.0 } }; var actual = miner.CreateDependencyGraph(eventList, matrix, 0.5, 0.0, 0, 10); var expected = new EventNode(event1, 0.8, new List<EventNode> { new EventNode(event2, 0.8, new List<EventNode> { new EventNode(event3, 0.8) }) }); Assert.AreEqual(expected.InnerEvent, actual.InnerEvent); Assert.AreEqual(expected.ListOfFollowers[0].InnerEvent, actual.ListOfFollowers[0].InnerEvent); Assert.AreEqual(expected.ListOfFollowers[0].ListOfFollowers[0].InnerEvent, actual.ListOfFollowers[0].ListOfFollowers[0].InnerEvent); }
public void CreateMinerTest() { var field = new Field(); var miner = MinerFactory.CreateMiner("Alpha Miner", field); Assert.IsInstanceOfType(miner, typeof(AlphaMiner)); miner = MinerFactory.CreateMiner("Heuristic Miner", field); Assert.IsInstanceOfType(miner, typeof(HeuristicMiner)); MinerSettings.ListOfMinerSettings["InductiveMiner"] = "InductiveMiner"; miner = MinerFactory.CreateMiner("Inductive Miner", field); Assert.IsInstanceOfType(miner, typeof(InductiveMiner)); MinerSettings.ListOfMinerSettings["InductiveMiner"] = "InductiveMinerInfrequent"; miner = MinerFactory.CreateMiner("Inductive Miner", field); Assert.IsInstanceOfType(miner, typeof(InductiveMinerInfrequent)); }
public void AlphaMinerBuildTheNetTest() { Field field = new Field { EventLog = GenerateTestLog() }; AlphaMiner alphaMiner = new AlphaMiner(field); PrivateObject priObj = new PrivateObject(alphaMiner); priObj.Invoke("DetectAllPlaces"); priObj.Invoke("DetectStartAndEndActivitiesInTraces"); priObj.Invoke("AddsPlacesTogether"); priObj.Invoke("RemoveAllDuplicatePlaces"); priObj.Invoke("BuildTheNet"); PetriNet petriNet = (PetriNet)priObj.GetField("_petriNet"); Place startPlace = petriNet.GetPlaceByName("start"); Place endPlace = petriNet.GetPlaceByName("end"); Assert.IsNotNull(petriNet); Assert.IsNotNull(startPlace); Assert.IsNotNull(endPlace); //MiningAlgorithm.AlphaMiner.PetriNet = new PetriNet(""); //MiningAlgorithm.AlphaMiner.ListOfStartActivities.Add("A"); //MiningAlgorithm.AlphaMiner.ListOfEndActivities.Add("D"); //MiningAlgorithm.AlphaMiner.ListOfActivities.Add("A"); //MiningAlgorithm.AlphaMiner.ListOfActivities.Add("B"); //MiningAlgorithm.AlphaMiner.ListOfActivities.Add("C"); //MiningAlgorithm.AlphaMiner.ListOfActivities.Add("D"); //MiningAlgorithm.AlphaMiner.ListOfActivities.Add("E"); //MiningAlgorithm.AlphaMiner.ListOfAlphaPlaces = ListAlphaMinerPlaces; //MiningAlgorithm.AlphaMiner.BuildTheNet(); }
/// <summary> /// Calculates a list of Field-Objects that represents the matrix in consecutive rows. It creates one object for each combination of chosen filters. /// </summary> /// <returns></returns> public void BuildMatrixFields() { MatrixFields = new List<Field>(); foreach (DimensionContent dc1 in SelectedDimensions[1].SelectedFilters) { foreach (DimensionContent dc2 in SelectedDimensions[0].SelectedFilters) { Field newField = new Field { Dimension1 = SelectedDimensions[0], Dimension2 = SelectedDimensions[1], DimensionContent1 = dc2, DimensionContent2 = dc1, AdditionalFiltersList = new List<SelectedDimension>() }; foreach (SelectedDimension filterDimension in SelectedDimensions.GetRange(2, SelectedDimensions.Count - 2)) if (filterDimension.Dimension.IsEmptyDimension == false) newField.AdditionalFiltersList.Add(filterDimension); MatrixFields.Add(newField); } } }
/// <summary> /// Opens a PMViewerWindow for the selected field. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void FieldDoubleClick(object sender, MouseButtonEventArgs e) { if (sender.GetType() == typeof(Button)) { _currentlySelectedField = ((sender as Button).Tag as Field); try { ModernWindow viewer = new Viewer.Viewer(_currentlySelectedField); viewer.Owner = Application.Current.MainWindow; viewer.Show(); } catch (ArgumentNullException ex) { ErrorHandling.ReportErrorToUser("Error: " + ex.Message); } } }
public void CreateMinerTestFail() { var field = new Field(); MinerFactory.CreateMiner("Not existing Miner", field); }
/// <summary> /// Returns a DataTable of the Fact-Table. /// </summary> /// <returns>A list of Facts.</returns> /// <author>Jannik Arndt, Bernhard Bruns, Moritz Eversmann, Bernd Nottbeck</author> public static List<List<Case>> GetFacts(List<SelectedDimension> selectedFactDimensions, List<SelectedDimension> selectedEventDimensions, Field field) { if (field == null) throw new NoParamsGivenException("No field given"); OpenConnection(); field.SqlCode = SqlCreator.GetSQLCode(selectedFactDimensions, selectedEventDimensions, field); return DatabaseConnection.GetFacts(field.SqlCode.Replace("\n", " ")); }
/// <summary> /// Adds information of the generated petri net to the information-list /// </summary> /// <param name="field">A field from the DataSelection</param> /// <param name="ProcessingTimeStart">the processing time start</param> /// <param name="ProcessingTimeEnd">the processing time end</param> /// <author>Christopher Licht</author> private void PetriNetInformation(Field field, ref TimeSpan ProcessingTimeStart, ref TimeSpan ProcessingTimeEnd) { _field.Information.Add("Total Processor Time", ((ProcessingTimeEnd - ProcessingTimeStart).TotalMilliseconds) + " ms"); _field.Information.Add("Number of Events", _petriNet.Transitions.Count.ToString()); _field.Information.Add("Number of Transitions", _petriNet.Transitions.Count.ToString()); _field.Information.Add("Number of Places", _petriNet.Places.Count.ToString()); _field.Information.Add("Events used", _petriNet.CountTransitionsWithoutANDs() + " of " + field.EventLog.ListOfUniqueEvents.Count); }
/// <summary> /// Saves the visualization, petrinet or the eventlog in the required format /// </summary> /// <param name="processModelCanvas">Canvas with the processmodel</param> /// <param name="selectedField">The field</param> /// <param name="unitTest">true if a unit test calls this method</param> /// <author>Thomas Meents, Bernhard Bruns, Moritz Eversmann, Naby M. Sow, Andrej Albrecht</author> public static bool Export(Canvas processModelCanvas, Field selectedField, bool unitTest = false) { if (!unitTest) GetProperties(); SaveFileDialog saveFileDialog = new SaveFileDialog { ValidateNames = true, AddExtension = true, FileName = FilenameTagReplace(DefaultFileName, selectedField), InitialDirectory = DefaultFilePath, Filter = ExporterFactory.getFilterString(processModelCanvas, selectedField), FilterIndex = DefaultFileType + 1, RestoreDirectory = true, OverwritePrompt = true }; //// for unit test //////////////// if (unitTest) { string filetype = ""; switch (DefaultFileType) { case 0: filetype = ".bmp"; break; case 1: filetype = ".gif"; break; case 2: filetype = ".jpeg"; break; case 3: filetype = ".png"; break; case 4: filetype = ".tiff"; break; case 5: filetype = ".dot"; break; case 6: filetype = ".pnml"; break; case 7: filetype = ".mxml"; break; } IExporter exporter = ExporterFactory.createExporter(filetype, processModelCanvas, selectedField); if (exporter.export(DefaultFilePath + DefaultFileName + filetype)) return true; return false; } //// /for unit test //////////////// if (saveFileDialog.ShowDialog() == true) { string filetype = Path.GetExtension(saveFileDialog.FileName); string filename = saveFileDialog.FileName; string filePath = Path.GetDirectoryName(saveFileDialog.FileName); IExporter exporter = ExporterFactory.createExporter(filetype, processModelCanvas, selectedField); if (exporter.export(filename)) { if (OpenFolderAferExport) Process.Start("explorer", filePath); return true; } return false; } return false; }
/// <summary> /// Load a list of facts and eventlogs in the fields. /// </summary> /// <param name="field"></param> /// <author>Bernhard Bruns,Thomas Meents, Moritz Eversmann</author> public static bool LoadFactsInField(Field field) { try { List<List<Case>> listOfFacts = DBWorker.GetFacts(MainWindow.MatrixSelection.SelectedDimensions, EventSelectionModel.GetInstance().SelectedDimensions, field); foreach (List<Case> fact in listOfFacts) if (fact != null) field.EventLog.Cases.AddRange(fact); return true; } catch (TimeoutException ex) { ErrorHandling.ReportErrorToUser("Error: Database Timeout. " + ex.Message); } catch (Exception ex) { if (ex is NoParamsGivenException || ex is NotImplementedException || ex is ArgumentException) ErrorHandling.ReportErrorToUser("Error: " + ex.Message); else throw; } return false; }
public void CreateDiffTest() { Field diffField = new Field(); var diff = DiffFactory.CreateDiff<SnapshotDiff>(diffField); Assert.IsInstanceOfType(diff, typeof(SnapshotDiff)); }
/// <summary> /// Goes through the dictionary and calls GetAdjacency on every combination of Events to create an adjacency matrix. /// </summary> /// <param name="field">A field of the data selection</param> /// <returns>Returns an adjacency matrix</returns> /// <author>Jannik Arndt</author> public double[,] CreateAdjacencyMatrix(Field field) { if (field == null) throw new ArgumentNullException("field", "The given field is null"); int count = field.EventLog.ListOfUniqueEvents.Count; var adjacencyMatrix = new double[count, count]; for (var row = 0; row < count; row++) { for (var column = 0; column < count; column++) { // The lower triangular matrix is the negative compliment of the upper one. if (column < row) adjacencyMatrix[row, column] = -adjacencyMatrix[column, row]; else { Event event1 = field.EventLog.ListOfUniqueEvents[row]; Event event2 = field.EventLog.ListOfUniqueEvents[column]; Double adjacency = GetAdjacency(event1, event2, field.EventLog); adjacencyMatrix[row, column] = Math.Round(adjacency, 3); } } } return adjacencyMatrix; }
/// <summary> /// Return a string which contains a sql-statement to count only unique events per field /// </summary> /// <param name="selectedDimensionList"></param> /// <param name="field"></param> /// <returns></returns> /// <author>Bernhard Bruns</author> public static string CreateUniqueEventCountSqlStatement(List<SelectedDimension> selectedDimensionList, Field field) { return SqlCreator.GetSQLCodeCountUniqueEvents(selectedDimensionList, null, field); }
/// <summary> /// Initializes the InductiveMiner instance. /// </summary> /// <param name="field">Corresponding field</param> /// <author>Krystian Zielonka, Thomas Meents, Bernd Nottbeck</author> public InductiveMinerInfrequent(Field field) : base(field) { }
/// <summary> /// Replaces tags with current values /// </summary> /// <param name="name">Filename</param> /// <param name="field">Selected field</param> /// <returns>Renamed filename</returns> /// <author>Thomas Meents</author> public static string FilenameTagReplace(String name, Field field = null) { string date = DateTime.Now.ToShortDateString(); date = date.Replace(".", "-"); StringBuilder stringBuilder = new StringBuilder(name); stringBuilder.Replace("#DATE#", date); stringBuilder.Replace("#USER#", Environment.UserName); if (field != null) { stringBuilder.Replace("#NAME#", field.Infotext); stringBuilder.Replace("#QUALITY#", field.ProcessModelQualityColor); } stringBuilder.Replace("/", "-"); stringBuilder.Replace(":", ""); stringBuilder.Replace(",", "_"); return stringBuilder.ToString(); }