package net.seninp.jmotif.sax;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.seninp.jmotif.sax.alphabet.Alphabet;
import net.seninp.jmotif.sax.alphabet.NormalAlphabet;
import net.seninp.jmotif.sax.datastructure.SAXRecord;
import net.seninp.jmotif.sax.datastructure.SAXRecords;
/**
* Test SAX factory methods.
*
* @author Pavel Senin
*
*/
public class TestSAXProcessor {
private static final String ts1File = "src/resources/test-data/timeseries01.csv";
private static final String ts2File = "src/resources/test-data/timeseries02.csv";
private static final String ts3File = "src/resources/test-data/timeseries03.csv";
private static final String ts1StrRep10 = "bcjkiheebb";
private static final String ts2StrRep10 = "bcefgijkdb";
private static final String ts1StrRep14 = "bcdijjhgfeecbb";
private static final String ts2StrRep14 = "bbdeeffhijjfbb";
private static final String ts1StrRep7 = "bcggfddba";
private static final String ts2StrRep7 = "accdefgda";
private static final int length = 15;
private static final int strLength = 10;
private static final Alphabet normalA = new NormalAlphabet();
private static final double delta = 0.001;
// logging stuff
//
private static final Logger LOGGER = LoggerFactory.getLogger(TestSAXProcessor.class);
/**
* Testing the concatenated time series SAX conversion.
*
* @throws NumberFormatException if error occurs.
* @throws IOException if error occurs.
* @throws SAXException if error occurs.
*/
@Test
public void testConnectedConversion() throws NumberFormatException, IOException, SAXException {
final SAXProcessor sp = new SAXProcessor();
final double[] ts = TSProcessor.readFileColumn(ts3File, 0, 0);
ArrayList<Integer> skips = new ArrayList<Integer>();
for (int i = 30 - 6; i < 30; i++) {
skips.add(i);
}
SAXRecords regularSAX = sp.ts2saxViaWindow(ts, 6, 3, normalA.getCuts(3),
NumerosityReductionStrategy.NONE, 0.01);
LOGGER.debug("NONE: there are " + regularSAX.getAllIndices().size() + " words: \n"
+ regularSAX.getSAXString(" ") + "\n" + regularSAX.getAllIndices());
SAXRecords saxData = sp.ts2saxViaWindowSkipping(ts, 6, 3, normalA.getCuts(3),
NumerosityReductionStrategy.NONE, 0.01, skips);
LOGGER.debug("NONE with skips: there are " + saxData.getAllIndices().size() + " words: \n"
+ saxData.getSAXString(" ") + "\n" + saxData.getAllIndices());
regularSAX = sp.ts2saxViaWindow(ts, 6, 3, normalA.getCuts(3), NumerosityReductionStrategy.EXACT,
0.01);
assertNotNull("asserting the processing result", regularSAX);
LOGGER.debug("EXACT: there are " + regularSAX.getAllIndices().size() + " words: \n"
+ regularSAX.getSAXString(" ") + "\n" + regularSAX.getAllIndices());
saxData = sp.ts2saxViaWindowSkipping(ts, 6, 3, normalA.getCuts(3),
NumerosityReductionStrategy.EXACT, 0.01, skips);
LOGGER.debug("EXACT with skips: there are " + saxData.getAllIndices().size() + " words: \n"
+ saxData.getSAXString(" ") + "\n" + saxData.getAllIndices());
}
/**
* Test the SAX conversion.
*
* @throws Exception if error occurs.
*/
@Test
public void testTs2SAXByChunks() throws Exception {
final SAXProcessor sp = new SAXProcessor();
final TSProcessor tp = new TSProcessor();
final double[] ts1 = TSProcessor.readFileColumn(ts1File, 0, length);
final double[] ts2 = TSProcessor.readFileColumn(ts2File, 0, length);
final double[] ser = { -1.0, -2.0, -1.0, 0.0, 2.0, 1.0, 1.0, 0.0 };
LOGGER.debug(" ** " + Arrays.toString(tp.paa(ser, 3)));
// series #1 goes here
SAXRecords ts1sax = sp.ts2saxByChunking(ts1, 10, normalA.getCuts(11), delta);
assertEquals("testing SAX", strLength, ts1sax.getSAXString("").length());
assertTrue("testing SAX", ts1StrRep10.equalsIgnoreCase(ts1sax.getSAXString("")));
// test positions
// bcjkiheebb
//
Integer[] bPositions = ts1sax.getByWord("b").getIndexes().toArray(new Integer[3]);
Arrays.sort(bPositions);
assertEquals(0, bPositions[0].intValue());
assertEquals(12, bPositions[1].intValue());
assertEquals(13, bPositions[2].intValue());
String ts1sax2 = sp.ts2saxByChunking(ts1, 14, normalA.getCuts(10), delta).getSAXString("");
assertEquals("testing SAX", 14, ts1sax2.length());
assertTrue("testing SAX", ts1StrRep14.equalsIgnoreCase(ts1sax2));
String ts1sax3 = sp.ts2saxByChunking(ts1, 9, normalA.getCuts(7), delta).getSAXString("");
assertEquals("testing SAX", 9, ts1sax3.length());
assertTrue("testing SAX", ts1StrRep7.equalsIgnoreCase(ts1sax3));
// series #2 goes here
String ts2sax = sp.ts2saxByChunking(ts2, 10, normalA.getCuts(11), delta).getSAXString("");
assertEquals("testing SAX", strLength, ts2sax.length());
assertTrue("testing SAX", ts2StrRep10.equalsIgnoreCase(ts2sax));
ts2sax = sp.ts2saxByChunking(ts2, 14, normalA.getCuts(10), delta).getSAXString("");
assertEquals("testing SAX", 14, ts2sax.length());
assertTrue("testing SAX", ts2StrRep14.equalsIgnoreCase(ts2sax));
ts2sax = sp.ts2saxByChunking(ts2, 9, normalA.getCuts(7), delta).getSAXString("");
assertEquals("testing SAX", 9, ts2sax.length());
assertTrue("testing SAX", ts2StrRep7.equalsIgnoreCase(ts2sax));
}
/**
* Test the SAX conversion.
*
* @throws Exception if error occurs.
*/
@Test
public void testTs2SAXByGlobalChunks() throws Exception {
final SAXProcessor sp = new SAXProcessor();
final double[] ts1 = TSProcessor.readFileColumn(ts1File, 0, length);
SAXRecords saxdata = sp.ts2saxViaWindowGlobalZNorm(ts1, 5, 5, normalA.getCuts(3),
NumerosityReductionStrategy.NONE, 0.01);
SAXRecord entry = saxdata.getByIndex(7);
// library(jmotif)
// library(data.table)
// dat<-fread("../resources/test-data/timeseries01.csv")
// zdat <- jmotif::znorm(dat$V1, 0.01)
// win = zdat[8:12]
// motif::series_to_chars(win, 3)
// [1] "c" "c" "b" "b" "b"
assertTrue("ccbbb".equalsIgnoreCase(String.valueOf(entry.getPayload())));
}
/**
* Test the discretization.
*
* @throws Exception if error occur.
*/
@Test
public void testTs2sax() throws Exception {
final TSProcessor tp = new TSProcessor();
final SAXProcessor sp = new SAXProcessor();
double[] ts2 = TSProcessor.readFileColumn(ts2File, 0, length);
String ts2str_0 = sp
.ts2saxByChunking(tp.subseriesByCopy(ts2, 0, 5), 5, normalA.getCuts(10), delta)
.getSAXString("");
String ts2str_3 = sp
.ts2saxByChunking(tp.subseriesByCopy(ts2, 3, 8), 5, normalA.getCuts(10), delta)
.getSAXString("");
String ts2str_7 = sp
.ts2saxByChunking(tp.subseriesByCopy(ts2, 7, 12), 5, normalA.getCuts(10), delta)
.getSAXString("");
SAXRecords ts2SAX = sp.ts2saxViaWindow(ts2, 5, 5, normalA.getCuts(10),
NumerosityReductionStrategy.NONE, delta);
assertEquals("Testing conversion", ts2.length - 5 + 1, ts2SAX.size());
assertNotNull("Testing ts2sax", ts2SAX.getByWord(ts2str_0));
assertNotNull("Testing ts2sax", ts2SAX.getByWord(ts2str_3));
assertNotNull("Testing ts2sax", ts2SAX.getByWord(ts2str_7));
assertEquals("Testing ts2sax", ts2SAX.getByWord(ts2str_0).getIndexes().iterator().next(),
new Integer(0));
assertEquals("Testing ts2sax", ts2SAX.getByWord(ts2str_3).getIndexes().iterator().next(),
new Integer(3));
assertEquals("Testing ts2sax", ts2SAX.getByWord(ts2str_7).getIndexes().iterator().next(),
new Integer(7));
SAXRecords ts2SAXerror = null;
try {
ts2SAXerror = sp.ts2saxViaWindow(ts2, ts2.length + 1, 5, normalA.getCuts(10),
NumerosityReductionStrategy.NONE, delta);
fail("Exception must be thrown!");
}
catch (SAXException e) {
assertNull(ts2SAXerror);
}
}
/**
* Test the MINDIST distance.
*
* @throws Exception if error occur.
*/
@Test
public void testMINDIST() {
final double a3distValue = 0.861455;
final double refDist = Math.sqrt(128.0 / 8.0)
* Math.sqrt(a3distValue * a3distValue + a3distValue * a3distValue);
final String a = "baabccbc";
final String b = "babcacca";
final SAXProcessor sp = new SAXProcessor();
// try the normal operation
try {
assertEquals(
sp.saxMinDist(a.toCharArray(), b.toCharArray(), normalA.getDistanceMatrix(3), 128, 8),
refDist, delta);
}
catch (SAXException e) {
fail("exception shall not be thrown!");
}
// try the abnormal operation -- not letter is in the word
try {
assertEquals(sp.saxMinDist("baabcc4c".toCharArray(), b.toCharArray(),
normalA.getDistanceMatrix(2), 128, 8), refDist, delta);
fail("exception not thrown!");
}
catch (SAXException e) {
assert true;
}
// try the abnormal operation -- length is not equal
try {
assertEquals(sp.saxMinDist("baabccc".toCharArray(), b.toCharArray(),
normalA.getDistanceMatrix(2), 128, 8), refDist, delta);
fail("exception not thrown!");
}
catch (SAXException e) {
assert true;
}
// try the abnormal operation -- "c" is not in the alphabet
try {
assertEquals(
sp.saxMinDist(a.toCharArray(), b.toCharArray(), normalA.getDistanceMatrix(2), 128, 8),
refDist, delta);
fail("exception not thrown!");
}
catch (SAXException e) {
assert true;
}
assertFalse(sp.checkMinDistIsZero(a.toCharArray(), b.toCharArray()));
assertTrue(sp.checkMinDistIsZero("aabbccdd".toCharArray(), "bbccddee".toCharArray()));
}
/**
* Test to string conversion.
*
*/
@Test
public void testTs2String() {
final double[] series = { -1., -2., -1., 0., 2., 1., 1., 0. };
final SAXProcessor sp = new SAXProcessor();
try {
assertTrue(String.valueOf(sp.ts2string(series, 3, normalA.getCuts(3), 0.001)).equals("acc"));
assertTrue(
String.valueOf(sp.ts2string(series, 8, normalA.getCuts(3), 0.001)).equals("aaabcccb"));
}
catch (SAXException e) {
fail("exception shall not be thrown!");
}
}
/**
* Test char distance.
*
*/
@Test
public void testCharDistance() {
final SAXProcessor sp = new SAXProcessor();
assertEquals(sp.charDistance('a', 'a'), 0);
assertEquals(sp.charDistance('a', 'c'), 2);
assertEquals(sp.charDistance('a', 'e'), 4);
}
/**
* Test str distance.
*
*/
@Test
public void testStrDistance() {
final SAXProcessor sp = new SAXProcessor();
try {
assertEquals(sp.strDistance("aaa".toCharArray(), "aaa".toCharArray()), 0);
assertEquals(sp.strDistance("aaa".toCharArray(), "aac".toCharArray()), 2);
assertEquals(sp.strDistance("aaa".toCharArray(), "abc".toCharArray()), 3);
}
catch (SAXException e) {
fail("exception shall not be thrown!");
}
try {
assertEquals(sp.strDistance("aaa".toCharArray(), "aaaa".toCharArray()), 0);
fail("exception shall be thrown!");
}
catch (SAXException e) {
assert true;
}
}
}