diff --git a/pom.xml b/pom.xml
index c13a79e..d711418 100644
--- a/pom.xml
+++ b/pom.xml
@@ -45,6 +45,11 @@
gson
2.8.9
+
+ org.apache.commons
+ commons-lang3
+ 3.12.0
+
diff --git a/src/main/java/dtu/qpms/MotifsFilter.java b/src/main/java/dtu/qpms/MotifsFilter.java
index bc21195..9350293 100644
--- a/src/main/java/dtu/qpms/MotifsFilter.java
+++ b/src/main/java/dtu/qpms/MotifsFilter.java
@@ -5,9 +5,11 @@
import java.util.HashSet;
import java.util.Set;
+import org.apache.commons.lang3.tuple.Pair;
import org.deckfour.xes.extension.std.XConceptExtension;
import org.deckfour.xes.in.XParser;
import org.deckfour.xes.in.XesXmlParser;
+import org.deckfour.xes.model.XAttributeMap;
import org.deckfour.xes.model.XEvent;
import org.deckfour.xes.model.XLog;
import org.deckfour.xes.model.XTrace;
@@ -47,9 +49,8 @@ public static void main(String[] args) throws Exception {
System.out.println("motifs max distance: " + maxDistance);
System.out.println("");
- Set> strings = new HashSet>();
Set> motifs = new HashSet>();
- MotifsFilterExecutor mf = new MotifsFilterExecutor(c);
+ MotifsFilterExecutor mf = new MotifsFilterExecutor(c);
XParser parser = new XesXmlParser();
@@ -59,11 +60,12 @@ public static void main(String[] args) throws Exception {
for (XTrace t : logStrings) {
Sequence s = new Sequence();
+ Sequence attributes = new Sequence();
for (XEvent e : t) {
s.add(XConceptExtension.instance().extractName(e));
+ attributes.add(e.getAttributes());
}
- strings.add(s);
- mf.addString(s);
+ mf.addString(s, attributes);
}
System.out.println("Done! - " + (System.currentTimeMillis() - time) + "ms");
@@ -84,17 +86,20 @@ public static void main(String[] args) throws Exception {
time = System.currentTimeMillis();
System.out.print("3. Filtering motifs... ");
- Set> replaced = mf.filter(maxDistance, ACTIVITY_NAME_ABSTRACTED_ACTIVITY);
+ Set, Sequence>> replaced = mf.filter(maxDistance, ACTIVITY_NAME_ABSTRACTED_ACTIVITY);
System.out.println("Done! - " + (System.currentTimeMillis() - time) + "ms");
time = System.currentTimeMillis();
System.out.print("4. Saving motifs... ");
int motifCounter = 1;
XLog logFiltered = XLogHelper.generateNewXLog("filtered");
- for(Sequence seq : replaced) {
+ for(Pair, Sequence> seq : replaced) {
XTrace t = XLogHelper.createTrace("case_" + motifCounter);
- for (String s : seq) {
- XLogHelper.insertEvent(t, s);
+ for (int i = 0; i < seq.getLeft().size(); i++) {
+ XEvent e = XLogHelper.xesFactory.createEvent();
+ e.setAttributes(seq.getRight().get(i));
+ XConceptExtension.instance().assignName(e, seq.getLeft().get(i));
+ t.add(e);
}
logFiltered.add(t);
motifCounter++;
diff --git a/src/main/java/dtu/qpms/model/MotifsFilterExecutor.java b/src/main/java/dtu/qpms/model/MotifsFilterExecutor.java
index 59d202c..363a61f 100644
--- a/src/main/java/dtu/qpms/model/MotifsFilterExecutor.java
+++ b/src/main/java/dtu/qpms/model/MotifsFilterExecutor.java
@@ -8,32 +8,34 @@
import java.util.Map;
import java.util.Set;
-public class MotifsFilterExecutor {
+import org.apache.commons.lang3.tuple.Pair;
+
+public class MotifsFilterExecutor {
private static final char TO_REPLACE = '!';
- private Set strings;
- private Set motifs;
+ private Set>> strings;
+ private Set>> motifs;
private CostMapping costs;
private Map charsToValues;
private Map valuesToChars;
public MotifsFilterExecutor(CostMapping costs) {
- this.strings = new HashSet();
- this.motifs = new HashSet();
+ this.strings = new HashSet>>();
+ this.motifs = new HashSet>>();
this.charsToValues = new HashMap();
this.valuesToChars = new HashMap();
this.costs = costs;
}
- public boolean addString(Sequence string) {
- return add(string, strings);
+ public boolean addString(Sequence string, Sequence attributes) {
+ return add(string, attributes, strings);
}
public boolean addMotif(Sequence motif) {
- return add(motif, motifs);
+ return add(motif, null, motifs);
}
- private boolean add(Sequence string, Set set) {
+ private boolean add(Sequence string, Sequence attributes, Set>> set) {
String s = "";
for (int i = 0; i < string.size(); i++) {
T t = string.get(i);
@@ -44,36 +46,42 @@ private boolean add(Sequence string, Set set) {
}
s += valuesToChars.get(t);
}
- return set.add(s);
+ return set.add(Pair.of(s, attributes));
}
- public Set> filter(double maxDistance, T replace) {
- Set> toReturn = new HashSet>();
- for (String s : filterStrings(maxDistance)) {
+ public Set, Sequence>> filter(double maxDistance, T replace) {
+ Set, Sequence>> toReturn = new HashSet, Sequence>>();
+ for (Pair> pair : filterStrings(maxDistance)) {
+ String s = pair.getLeft();
Sequence seq = new Sequence();
+ Sequence attSeq = new Sequence();
for (int i = 0; i < s.length(); i++) {
Character c = s.charAt(i);
if (c.equals(TO_REPLACE)) {
seq.add(replace);
+ attSeq.add(pair.getRight().get(i));
} else {
seq.add(charsToValues.get(c));
+ attSeq.add(pair.getRight().get(i));
}
}
- toReturn.add(seq);
+ toReturn.add(Pair.of(seq, attSeq));
}
return toReturn;
}
- private Set filterStrings(double maxDistance) {
+ private Set>> filterStrings(double maxDistance) {
if (motifs.isEmpty()) {
return strings;
}
HammingDistance hamming = new HammingDistance(costs, charsToValues);
- Set toReturn = new HashSet();
- int motifLength = motifs.iterator().next().length();
- for (String s : strings) {
+ Set>> toReturn = new HashSet>>();
+ int motifLength = motifs.iterator().next().getLeft().length();
+ for (Pair> pair : strings) {
+ String s = pair.getLeft();
List indexesWithMotifs = new ArrayList();
- for (String m : motifs) {
+ for (Pair> motifPair : motifs) {
+ String m = motifPair.getLeft();
int stringLength = s.length();
if (stringLength >= motifLength) {
for (int i = 0; i <= stringLength - motifLength; i++) {
@@ -85,7 +93,7 @@ private Set filterStrings(double maxDistance) {
}
}
if (indexesWithMotifs.size() == 0) {
- toReturn.add(s);
+ toReturn.add(Pair.of(s, pair.getRight()));
} else {
Collections.sort(indexesWithMotifs);
@@ -97,18 +105,31 @@ private Set filterStrings(double maxDistance) {
}
String replacement = "";
+ Sequence attributes = new Sequence();
for (int i = 0; i < indexesWithMotifsToReplace.size(); i++) {
if (i==0) {
replacement += s.substring(0, indexesWithMotifsToReplace.get(i));
+ for (int j = 0; j < indexesWithMotifsToReplace.get(i); j++) {
+ attributes.add(pair.getRight().get(j));
+ }
} else {
replacement += s.substring(indexesWithMotifsToReplace.get(i - 1) + motifLength, indexesWithMotifsToReplace.get(i));
+ for (int j = indexesWithMotifsToReplace.get(i - 1) + motifLength; j < indexesWithMotifsToReplace.get(i); j++) {
+ attributes.add(pair.getRight().get(j));
+ }
}
+
replacement += TO_REPLACE;
+ attributes.add(pair.getRight().get(indexesWithMotifsToReplace.get(i)));
+
if (i + 1 == indexesWithMotifsToReplace.size()) {
replacement += s.substring(indexesWithMotifsToReplace.get(i) + motifLength);
+ for (int j = indexesWithMotifsToReplace.get(i) + motifLength; j < s.length(); j++) {
+ attributes.add(pair.getRight().get(j));
+ }
}
}
- toReturn.add(replacement);
+ toReturn.add(Pair.of(replacement, attributes));
}
}
return toReturn;
diff --git a/src/main/java/dtu/qpms/utils/XLogHelper.java b/src/main/java/dtu/qpms/utils/XLogHelper.java
index 374c76f..c133a82 100644
--- a/src/main/java/dtu/qpms/utils/XLogHelper.java
+++ b/src/main/java/dtu/qpms/utils/XLogHelper.java
@@ -68,7 +68,7 @@
*/
public class XLogHelper {
- private static XFactory xesFactory = new XFactoryNaiveImpl();
+ public static XFactory xesFactory = new XFactoryNaiveImpl();
private static XExtensionManager xesExtensionManager = XExtensionManager.instance();
/**
diff --git a/test-files/toy-input.xes b/test-files/toy-input.xes
index 9893949..09b5c47 100644
--- a/test-files/toy-input.xes
+++ b/test-files/toy-input.xes
@@ -3,17 +3,26 @@
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+