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();
 }