diff --git a/examples/forErna/std_analysis_erna_observations.xml b/examples/forErna/std_analysis_erna_observations.xml index d9c0dc0528..a0e5857aa1 100644 --- a/examples/forErna/std_analysis_erna_observations.xml +++ b/examples/forErna/std_analysis_erna_observations.xml @@ -5,11 +5,11 @@ --> - + - + diff --git a/pom.xml b/pom.xml index 7b5a957da4..b5c807bf31 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ de.sfb876 fact-tools fact-tools - 1.0.2 + 1.0.3-SNAPSHOT http://sfb876.de/fact-tools/ diff --git a/src/main/java/fact/auxservice/SqliteService.java b/src/main/java/fact/auxservice/SqliteService.java deleted file mode 100644 index d649257ad1..0000000000 --- a/src/main/java/fact/auxservice/SqliteService.java +++ /dev/null @@ -1,270 +0,0 @@ -package fact.auxservice; - -import com.google.common.cache.*; -import fact.auxservice.strategies.AuxPointStrategy; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.tmatesoft.sqljet.core.SqlJetException; -import org.tmatesoft.sqljet.core.SqlJetTransactionMode; -import org.tmatesoft.sqljet.core.table.ISqlJetCursor; -import org.tmatesoft.sqljet.core.table.ISqlJetTable; -import org.tmatesoft.sqljet.core.table.SqlJetDb; -import stream.annotations.Parameter; -import stream.io.SourceURL; - -import java.io.File; -import java.io.IOException; -import java.io.Serializable; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.util.HashMap; -import java.util.Map; -import java.util.TreeSet; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; - - -/** - * This implements an AuxiliaryService {@link AuxiliaryService} providing data from a sqlite file. - * Can handle TRACKING and SOURCE information. - *

- * Created by kai on 01.03.15. - */ -public class SqliteService implements AuxiliaryService { - - static Logger log = LoggerFactory.getLogger(SqliteService.class); - - @Parameter(required = true, description = "The URL to the sqlite database file. ") - private SourceURL url; - - @Parameter(required = false, description = "Expiry time for entries in the cache.", defaultValue = "10 Minutes") - private int window = 10; - - private LoadingCache> cache = CacheBuilder.newBuilder() - .maximumSize(100) - .expireAfterAccess(window, TimeUnit.MINUTES) - .removalListener(new RemovalListener() { - @Override - public void onRemoval(RemovalNotification notification) { - log.info("Removing Data {} from cache for cause {}", notification.toString(), notification.getCause()); - } - }) - .build(new CacheLoader>() { - @Override - public TreeSet load(AuxDataCacheKey key) throws Exception { - log.info("Building entry for service {} and key: {}", key.service, key.roundedTimeStamp); - return loadDataFromDataBase(key.service, key.roundedTimeStamp); - } - }); - - public static ZonedDateTime floorToQuarterHour(ZonedDateTime time) { - ZonedDateTime t = time.withZoneSameInstant(ZoneOffset.UTC).withSecond(0); - - int oldMinute = t.getMinute(); - int newMinute = 15 * (int) Math.floor(oldMinute / 15.0); - - return t.withMinute(newMinute); - } - - - public class AuxDataCacheKey { - private final AuxiliaryServiceName service; - private final ZonedDateTime roundedTimeStamp; - - public AuxDataCacheKey(AuxiliaryServiceName service, ZonedDateTime timeStamp) { - this.service = service; - this.roundedTimeStamp = floorToQuarterHour(timeStamp); - } - - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - AuxDataCacheKey cacheKey = (AuxDataCacheKey) o; - - if (!roundedTimeStamp.equals(cacheKey.roundedTimeStamp)) return false; - - return service == cacheKey.service; - - } - - @Override - public int hashCode() { - int result = service.hashCode(); - result = 31 * result + roundedTimeStamp.hashCode(); - return result; - } - } - - - /** - * public for unit testing purposes - * - * @param service the name of the aux data to fetch - * @param time the time stamp of the data event - * @return the TreeSet containing the AuxPoints - */ - public TreeSet loadDataFromDataBase(AuxiliaryServiceName service, ZonedDateTime time) { - TreeSet result = new TreeSet<>(); - - try { -// log.info("Querying Database for " + service.toString() + " data for time " + time.toString()); - - SqlJetDb db = SqlJetDb.open(new File(url.getFile()), true); - ISqlJetTable table = db.getTable(service.toString()); - ISqlJetCursor cursor = null; - try { - - db.beginTransaction(SqlJetTransactionMode.READ_ONLY); - try { - if (service == AuxiliaryServiceName.DRIVE_CONTROL_TRACKING_POSITION) { - - - String earlierTime = time.minusHours(4).toString(); - String[] dateAndTime = earlierTime.split("T"); - String[] timeSplitZone = dateAndTime[1].split("Z"); - String earlier = dateAndTime[0] + " " + timeSplitZone[0].substring(0, 8); - - String laterTime = time.plusMinutes(window).toString(); - dateAndTime = laterTime.split("T"); - timeSplitZone = dateAndTime[1].split("Z"); - String later = dateAndTime[0] + " " + timeSplitZone[0].substring(0, 8); - - cursor = table.scope("ix_DRIVE_CONTROL_TRACKING_POSITION_Time", new Object[]{earlier}, new Object[]{later}); - result = getTrackingDataFromCursor(cursor); - } else if (service == AuxiliaryServiceName.DRIVE_CONTROL_SOURCE_POSITION) { - //source position is slower. get data from several hours ago. - String earlierTime = time.minusHours(4).toString(); - String[] dateAndTime = earlierTime.split("T"); - String[] timeSplitZone = dateAndTime[1].split("Z"); - String earlier = dateAndTime[0] + " " + timeSplitZone[0].substring(0, 8); - - String laterTime = time.plusMinutes(window).toString(); - dateAndTime = laterTime.split("T"); - timeSplitZone = dateAndTime[1].split("Z"); - String later = dateAndTime[0] + " " + timeSplitZone[0].substring(0, 8); - - cursor = table.scope("ix_DRIVE_CONTROL_SOURCE_POSITION_Time", new Object[]{earlier}, new Object[]{later}); - result = getSourceDataFromCursor(cursor); - } else { - throw new RuntimeException("This service only provides data from DRIVE_CONTROL_SOURCE_POSITION and TRACKING files"); - } - } finally { - if (cursor != null) { - cursor.close(); - } - } - - } finally { - db.commit(); - db.close(); - } - - } catch (SqlJetException e) { - e.printStackTrace(); - } - return result; - } - - private TreeSet getSourceDataFromCursor(ISqlJetCursor cursor) throws SqlJetException { - TreeSet result = new TreeSet<>(); - if (!cursor.eof()) { - do { - Map m = new HashMap<>(); - m.put("QoS", cursor.getInteger("QoS")); - //getFloat actually returns a double. WTF - m.put("Name", cursor.getString("Name")); - m.put("Angle", cursor.getFloat("Angle")); - m.put("Ra_src", cursor.getFloat("Ra_src")); - m.put("Dec_src", cursor.getFloat("Dec_src")); - // m.put("Ra_cmd", cursor.getFloat("Ra_cmd")); - // m.put("Dec_cmd", cursor.getFloat("Dec_cmd")); - m.put("Offset", cursor.getFloat("Offset")); - - String tempTime = cursor.getString("Time"); - tempTime = tempTime.concat("+00:00"); - tempTime = tempTime.replace(" ", "T"); - ZonedDateTime t = ZonedDateTime.parse(tempTime); - result.add(new AuxPoint(t, m)); - } while (cursor.next()); - } - return result; - } - - private TreeSet getTrackingDataFromCursor(ISqlJetCursor cursor) throws SqlJetException { - TreeSet result = new TreeSet<>(); - if (!cursor.eof()) { - do { - Map m = new HashMap<>(); - m.put("QoS", cursor.getInteger("QoS")); - //getFloat actually returns a double. WTF - m.put("Zd", cursor.getFloat("Zd")); - m.put("Az", cursor.getFloat("Az")); - m.put("Ra", cursor.getFloat("Ra")); - m.put("Dec", cursor.getFloat("Dec")); - m.put("dZd", cursor.getFloat("dZd")); - m.put("dAz", cursor.getFloat("dAz")); - m.put("dev", cursor.getFloat("dev")); - - - String tempTime = cursor.getString("Time"); - tempTime = tempTime.concat("+00:00"); - tempTime = tempTime.replace(" ", "T"); - - - ZonedDateTime t = ZonedDateTime.parse(tempTime); - - result.add(new AuxPoint(t, m)); - } while (cursor.next()); - } - return result; - } - - - /** - * Get auxiliary data from the cache connected to the sqlite database holding drive information. - * - * @param service The service to query. - * @param eventTimeStamp The timestamp of your current event. - * @return the data closest to the eventtimestamp which is found in the database according to the strategy. - */ - @Override - public AuxPoint getAuxiliaryData(AuxiliaryServiceName service, ZonedDateTime eventTimeStamp, AuxPointStrategy strategy) throws IOException { - try { - AuxDataCacheKey key = new AuxDataCacheKey(service, eventTimeStamp); - //this set might not contain the data we need - TreeSet set = cache.get(key); - AuxPoint a = strategy.getPointFromTreeSet(set, eventTimeStamp); - if (a == null) { - throw new IOException("No auxpoint found for the given timestamp " + eventTimeStamp); - } - TimeUnit tu = TimeUnit.SECONDS; - long difference = eventTimeStamp.toEpochSecond() - a.getTimeStamp().toEpochSecond(); - long seconds = tu.toSeconds(difference); - log.debug("Seconds between event and {} auxpoint : {}", service, seconds); - return strategy.getPointFromTreeSet(set, eventTimeStamp); - - } catch (ExecutionException e) { - throw new IOException("Could not load data from Database. Is the database readable?"); -// e.printStackTrace(); - } - } - - - @Override - public void reset() throws Exception { - log.info("Reset called on {}", this.getClass()); - } - - public void setUrl(SourceURL url) { - this.url = url; - } - - public void setWindow(int window) { - this.window = window; - } - - -} diff --git a/src/test/java/fact/services/SqliteTest.java b/src/test/java/fact/services/SqliteTest.java deleted file mode 100644 index 0769e4ee7f..0000000000 --- a/src/test/java/fact/services/SqliteTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package fact.services; - -import fact.auxservice.AuxPoint; -import fact.auxservice.AuxiliaryServiceName; -import fact.auxservice.SqliteService; -import fact.auxservice.strategies.Closest; -import org.junit.Test; -import stream.io.SourceURL; - -import java.io.IOException; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.util.TreeSet; - -import static org.hamcrest.core.Is.is; -import static org.hamcrest.core.IsNot.not; -import static org.hamcrest.core.IsNull.nullValue; -import static org.junit.Assert.assertThat; - -/** - * Test the implementation of the sqliteservice test by querying the test files. - * Created by kai on 06.12.15. - */ -public class SqliteTest { - - @Test - public void testSourcePosition() throws Exception { - SqliteService s = new SqliteService(); - s.setUrl(new SourceURL(SqliteTest.class.getResource("/drive_control_unittest_20140118_19.sqlite"))); - - ZonedDateTime t = ZonedDateTime.parse("2014-01-19T01:40:33+00:00"); - - TreeSet r = s.loadDataFromDataBase(AuxiliaryServiceName.DRIVE_CONTROL_SOURCE_POSITION, t); - - assertThat(r, is(not(nullValue()))); - - ZonedDateTime first = r.first().getTimeStamp(); - ZonedDateTime last = r.last().getTimeStamp(); - - - assertThat(first, is(ZonedDateTime.parse("2014-01-19T01:22:18.045+00:00"))); - assertThat(last, is(ZonedDateTime.parse("2014-01-19T01:42:58.391+00:00"))); - assertThat(r.size(), is(9)); - } - - @Test - public void testSourcePositionInMay() throws Exception { - SqliteService s = new SqliteService(); - s.setUrl(new SourceURL(SqliteTest.class.getResource("/drive_control_5_20.sqlite"))); - ZonedDateTime t = ZonedDateTime.parse("2014-05-20T23:46:14.560Z"); - AuxPoint auxiliaryData = s.getAuxiliaryData(AuxiliaryServiceName.DRIVE_CONTROL_SOURCE_POSITION, t, new Closest()); - assertThat(auxiliaryData, is(not(nullValue()))); - } - - /** - * Should deliver the same result as - * SELECT * FROM DRIVE_CONTROL_TRACKING_POSITION WHERE Time BETWEEN "2014-01-19 01:33:00" AND "2014-01-19 01:44:00" - * on the test DB - * - * @throws Exception - */ - @Test - public void testTrackingPosition() throws Exception { - SqliteService s = new SqliteService(); - s.setUrl(new SourceURL(SqliteTest.class.getResource("/drive_control_unittest_20140118_19.sqlite"))); - - ZonedDateTime t = ZonedDateTime.parse("2014-01-19T01:34:00.04+00:00"); - TreeSet r = s.loadDataFromDataBase(AuxiliaryServiceName.DRIVE_CONTROL_TRACKING_POSITION, t); - - assertThat(r, is(not(nullValue()))); - - ZonedDateTime first = r.first().getTimeStamp(); - ZonedDateTime last = r.last().getTimeStamp(); - - assertThat(first, is(ZonedDateTime.parse("2014-01-19T01:33:17.164+00:00"))); - assertThat(last, is(ZonedDateTime.parse("2014-01-19T01:43:58.684+00:00"))); - assertThat(r.size(), is(480)); - } - - @Test - public void testTimeFlooring() throws IOException { - ZonedDateTime time = ZonedDateTime.of(1987, 9, 20, 12, 40, 34, 0, ZoneOffset.UTC); - ZonedDateTime roundedTime = SqliteService.floorToQuarterHour(time); - assertThat(roundedTime, is(ZonedDateTime.of(1987, 9, 20, 12, 30, 00, 0, ZoneOffset.UTC))); - - time = ZonedDateTime.of(1987, 9, 20, 23, 59, 59, 0, ZoneOffset.UTC); - roundedTime = SqliteService.floorToQuarterHour(time); - assertThat(roundedTime, is(ZonedDateTime.of(1987, 9, 20, 23, 45, 00, 0, ZoneOffset.UTC))); - - - time = ZonedDateTime.of(1987, 9, 20, 00, 00, 01, 0, ZoneOffset.UTC); - roundedTime = SqliteService.floorToQuarterHour(time); - assertThat(roundedTime, is(ZonedDateTime.of(1987, 9, 20, 00, 00, 00, 0, ZoneOffset.UTC))); - } - - -}