From c1d8482760895e85aa9e462038fb50ea87478980 Mon Sep 17 00:00:00 2001
From: FKD13 <44001949+FKD13@users.noreply.github.com>
Date: Mon, 25 Mar 2024 20:27:51 +0100
Subject: [PATCH] quick cleanup
---
.gitignore | 4 +-
.idea/$PRODUCT_WORKSPACE_FILE$ | 18 --
.idea/.gitignore | 2 -
.idea/.name | 1 -
.idea/compiler.xml | 6 -
.idea/dataSources.xml | 23 --
.idea/jarRepositories.xml | 25 --
.idea/jpa-buddy.xml | 6 -
.idea/misc.xml | 8 -
.idea/runConfigurations/Telraam__build_.xml | 23 --
.../Telraam__migrateDevelopmentDatabase_.xml | 21 --
.../Telraam__migrateProductionDatabase_.xml | 21 --
.../Telraam__migrateTestingDatabase_.xml | 21 --
.idea/runConfigurations/Telraam__runDev_.xml | 21 --
.idea/runConfigurations/Telraam__runProd_.xml | 21 --
.idea/runConfigurations/Telraam__test_.xml | 26 --
.../Telraam__test_force_.xml | 26 --
.idea/sonarlint-state.xml | 6 -
.idea/sonarlint.xml | 8 -
.idea/sqldialects.xml | 7 -
.idea/vcs.xml | 6 -
src/main/java/telraam/App.java | 2 +-
src/main/java/telraam/database/models/Id.java | 19 --
.../RobustLapper.java | 2 +-
.../logic/{ => simple}/SimpleLapper.java | 3 +-
.../telraam/logic/viterbi/ViterbiLapper.java | 292 ------------------
.../viterbi/ViterbiLapperConfiguration.java | 42 ---
.../logic/viterbi/ViterbiLapperResource.java | 61 ----
.../algorithm/InvalidParameterException.java | 7 -
.../viterbi/algorithm/ViterbiAlgorithm.java | 127 --------
.../logic/viterbi/algorithm/ViterbiModel.java | 30 --
.../logic/viterbi/algorithm/ViterbiState.java | 25 --
src/main/java/telraam/station/Fetcher.java | 2 +
.../station/{ => models}/RonnyDetection.java | 2 +-
.../station/{ => models}/RonnyResponse.java | 2 +-
src/main/resources/banner.txt | 9 +-
.../java/telraam/logic/SimpleLapperTest.java | 1 +
37 files changed, 20 insertions(+), 906 deletions(-)
delete mode 100644 .idea/$PRODUCT_WORKSPACE_FILE$
delete mode 100644 .idea/.gitignore
delete mode 100644 .idea/.name
delete mode 100644 .idea/compiler.xml
delete mode 100644 .idea/dataSources.xml
delete mode 100644 .idea/jarRepositories.xml
delete mode 100644 .idea/jpa-buddy.xml
delete mode 100644 .idea/misc.xml
delete mode 100644 .idea/runConfigurations/Telraam__build_.xml
delete mode 100644 .idea/runConfigurations/Telraam__migrateDevelopmentDatabase_.xml
delete mode 100644 .idea/runConfigurations/Telraam__migrateProductionDatabase_.xml
delete mode 100644 .idea/runConfigurations/Telraam__migrateTestingDatabase_.xml
delete mode 100644 .idea/runConfigurations/Telraam__runDev_.xml
delete mode 100644 .idea/runConfigurations/Telraam__runProd_.xml
delete mode 100644 .idea/runConfigurations/Telraam__test_.xml
delete mode 100644 .idea/runConfigurations/Telraam__test_force_.xml
delete mode 100644 .idea/sonarlint-state.xml
delete mode 100644 .idea/sonarlint.xml
delete mode 100644 .idea/sqldialects.xml
delete mode 100644 .idea/vcs.xml
delete mode 100644 src/main/java/telraam/database/models/Id.java
rename src/main/java/telraam/logic/{robustLapper => robust}/RobustLapper.java (99%)
rename src/main/java/telraam/logic/{ => simple}/SimpleLapper.java (97%)
delete mode 100644 src/main/java/telraam/logic/viterbi/ViterbiLapper.java
delete mode 100644 src/main/java/telraam/logic/viterbi/ViterbiLapperConfiguration.java
delete mode 100644 src/main/java/telraam/logic/viterbi/ViterbiLapperResource.java
delete mode 100644 src/main/java/telraam/logic/viterbi/algorithm/InvalidParameterException.java
delete mode 100644 src/main/java/telraam/logic/viterbi/algorithm/ViterbiAlgorithm.java
delete mode 100644 src/main/java/telraam/logic/viterbi/algorithm/ViterbiModel.java
delete mode 100644 src/main/java/telraam/logic/viterbi/algorithm/ViterbiState.java
rename src/main/java/telraam/station/{ => models}/RonnyDetection.java (90%)
rename src/main/java/telraam/station/{ => models}/RonnyResponse.java (87%)
diff --git a/.gitignore b/.gitignore
index b55c818..95ddd25 100644
--- a/.gitignore
+++ b/.gitignore
@@ -192,4 +192,6 @@ flycheck_*.el
!gradle-wrapper.jar
-node_modules/
\ No newline at end of file
+node_modules/
+
+.idea
\ No newline at end of file
diff --git a/.idea/$PRODUCT_WORKSPACE_FILE$ b/.idea/$PRODUCT_WORKSPACE_FILE$
deleted file mode 100644
index 96ce66b..0000000
--- a/.idea/$PRODUCT_WORKSPACE_FILE$
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 5c98b42..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# Default ignored files
-/workspace.xml
\ No newline at end of file
diff --git a/.idea/.name b/.idea/.name
deleted file mode 100644
index 780c8da..0000000
--- a/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-telraam
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
deleted file mode 100644
index 659bf43..0000000
--- a/.idea/compiler.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
deleted file mode 100644
index f37c315..0000000
--- a/.idea/dataSources.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
- postgresql
- true
- org.postgresql.Driver
- jdbc:postgresql://localhost:5432/telraam_dev
-
-
- sqlite.xerial
- true
- org.sqlite.JDBC
- jdbc:sqlite::memory:
-
-
- postgresql
- true
- org.postgresql.Driver
- jdbc:postgresql://localhost:5432/telraam_dev
-
-
-
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
deleted file mode 100644
index b3e9cbd..0000000
--- a/.idea/jarRepositories.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/jpa-buddy.xml b/.idea/jpa-buddy.xml
deleted file mode 100644
index d08f400..0000000
--- a/.idea/jpa-buddy.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 240ddf3..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/Telraam__build_.xml b/.idea/runConfigurations/Telraam__build_.xml
deleted file mode 100644
index 0d73339..0000000
--- a/.idea/runConfigurations/Telraam__build_.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- true
- false
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/Telraam__migrateDevelopmentDatabase_.xml b/.idea/runConfigurations/Telraam__migrateDevelopmentDatabase_.xml
deleted file mode 100644
index 202127f..0000000
--- a/.idea/runConfigurations/Telraam__migrateDevelopmentDatabase_.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/Telraam__migrateProductionDatabase_.xml b/.idea/runConfigurations/Telraam__migrateProductionDatabase_.xml
deleted file mode 100644
index ffc82b4..0000000
--- a/.idea/runConfigurations/Telraam__migrateProductionDatabase_.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/Telraam__migrateTestingDatabase_.xml b/.idea/runConfigurations/Telraam__migrateTestingDatabase_.xml
deleted file mode 100644
index b2859c2..0000000
--- a/.idea/runConfigurations/Telraam__migrateTestingDatabase_.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/Telraam__runDev_.xml b/.idea/runConfigurations/Telraam__runDev_.xml
deleted file mode 100644
index c3766a2..0000000
--- a/.idea/runConfigurations/Telraam__runDev_.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/Telraam__runProd_.xml b/.idea/runConfigurations/Telraam__runProd_.xml
deleted file mode 100644
index 0f6b693..0000000
--- a/.idea/runConfigurations/Telraam__runProd_.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/Telraam__test_.xml b/.idea/runConfigurations/Telraam__test_.xml
deleted file mode 100644
index fdffce2..0000000
--- a/.idea/runConfigurations/Telraam__test_.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
-
\ No newline at end of file
diff --git a/.idea/runConfigurations/Telraam__test_force_.xml b/.idea/runConfigurations/Telraam__test_force_.xml
deleted file mode 100644
index f18cffe..0000000
--- a/.idea/runConfigurations/Telraam__test_force_.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
-
\ No newline at end of file
diff --git a/.idea/sonarlint-state.xml b/.idea/sonarlint-state.xml
deleted file mode 100644
index 0b9835d..0000000
--- a/.idea/sonarlint-state.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
- 1634050067000
-
-
\ No newline at end of file
diff --git a/.idea/sonarlint.xml b/.idea/sonarlint.xml
deleted file mode 100644
index 4b4f6a7..0000000
--- a/.idea/sonarlint.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml
deleted file mode 100644
index 0840fc3..0000000
--- a/.idea/sqldialects.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1dd..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/java/telraam/App.java b/src/main/java/telraam/App.java
index a4ba783..243edc8 100644
--- a/src/main/java/telraam/App.java
+++ b/src/main/java/telraam/App.java
@@ -16,7 +16,7 @@
import telraam.healthchecks.TemplateHealthCheck;
import telraam.logic.Lapper;
import telraam.logic.external.ExternalLapper;
-import telraam.logic.robustLapper.RobustLapper;
+import telraam.logic.robust.RobustLapper;
import telraam.station.Fetcher;
import telraam.util.AcceptedLapsUtil;
diff --git a/src/main/java/telraam/database/models/Id.java b/src/main/java/telraam/database/models/Id.java
deleted file mode 100644
index 97132af..0000000
--- a/src/main/java/telraam/database/models/Id.java
+++ /dev/null
@@ -1,19 +0,0 @@
-package telraam.database.models;
-
-public class Id {
-
- private int id;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- @Override
- public String toString() {
- return String.format("Id: %d", id);
- }
-}
\ No newline at end of file
diff --git a/src/main/java/telraam/logic/robustLapper/RobustLapper.java b/src/main/java/telraam/logic/robust/RobustLapper.java
similarity index 99%
rename from src/main/java/telraam/logic/robustLapper/RobustLapper.java
rename to src/main/java/telraam/logic/robust/RobustLapper.java
index 0477875..07335c4 100644
--- a/src/main/java/telraam/logic/robustLapper/RobustLapper.java
+++ b/src/main/java/telraam/logic/robust/RobustLapper.java
@@ -1,4 +1,4 @@
-package telraam.logic.robustLapper;
+package telraam.logic.robust;
import io.dropwizard.jersey.setup.JerseyEnvironment;
import org.jdbi.v3.core.Jdbi;
diff --git a/src/main/java/telraam/logic/SimpleLapper.java b/src/main/java/telraam/logic/simple/SimpleLapper.java
similarity index 97%
rename from src/main/java/telraam/logic/SimpleLapper.java
rename to src/main/java/telraam/logic/simple/SimpleLapper.java
index 5ed367e..6acc326 100644
--- a/src/main/java/telraam/logic/SimpleLapper.java
+++ b/src/main/java/telraam/logic/simple/SimpleLapper.java
@@ -1,10 +1,11 @@
-package telraam.logic;
+package telraam.logic.simple;
import io.dropwizard.jersey.setup.JerseyEnvironment;
import org.jdbi.v3.core.Jdbi;
import telraam.database.daos.LapDAO;
import telraam.database.daos.LapSourceDAO;
import telraam.database.models.*;
+import telraam.logic.Lapper;
import java.util.ArrayList;
import java.util.HashMap;
diff --git a/src/main/java/telraam/logic/viterbi/ViterbiLapper.java b/src/main/java/telraam/logic/viterbi/ViterbiLapper.java
deleted file mode 100644
index 980d891..0000000
--- a/src/main/java/telraam/logic/viterbi/ViterbiLapper.java
+++ /dev/null
@@ -1,292 +0,0 @@
-package telraam.logic.viterbi;
-
-import io.dropwizard.jersey.setup.JerseyEnvironment;
-import org.jdbi.v3.core.Jdbi;
-import telraam.database.daos.*;
-import telraam.database.models.*;
-import telraam.logic.Lapper;
-import telraam.logic.viterbi.algorithm.ViterbiAlgorithm;
-import telraam.logic.viterbi.algorithm.ViterbiModel;
-import telraam.logic.viterbi.algorithm.ViterbiState;
-
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.time.Instant;
-import java.util.*;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-
-public class ViterbiLapper implements Lapper {
- static final String SOURCE_NAME = "viterbi-lapper";
-
- private final ViterbiLapperConfiguration config;
- private Map currentStates;
- private final Jdbi jdbi;
- private final int lapSourceId;
- private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
- private boolean debounceScheduled;
- private final Logger logger = Logger.getLogger(ViterbiLapper.class.getName());
-
- public ViterbiLapper(Jdbi jdbi) {
- this(jdbi, new ViterbiLapperConfiguration());
- }
-
- public ViterbiLapper(Jdbi jdbi, ViterbiLapperConfiguration configuration) {
- this.jdbi = jdbi;
- this.config = configuration;
- this.currentStates = new HashMap<>();
- this.debounceScheduled = false;
-
- LapSourceDAO lapSourceDAO = jdbi.onDemand(LapSourceDAO.class);
-
- lapSourceDAO.getByName(ViterbiLapper.SOURCE_NAME).orElseThrow();
-
- this.lapSourceId = lapSourceDAO.getByName(ViterbiLapper.SOURCE_NAME).get().getId();
- }
-
-
- private ViterbiModel createViterbiModel() {
- StationDAO stationDAO = jdbi.onDemand(StationDAO.class);
-
- // We will construct one segment for each station, which will represent its
- // neighbourhood.
- List stations = stationDAO.getAll();
- stations.sort(Comparator.comparing(Station::getDistanceFromStart));
-
-
- // ***********************************
- // Build detection probability mapping
- // ***********************************
- Map> emissionProbabilities = new HashMap<>();
- for (int segmentNum = 0; segmentNum < stations.size(); segmentNum++) {
- Map probas = new HashMap<>();
- for (int stationNum = 0; stationNum < stations.size(); stationNum++) {
- int stationId = stations.get(stationNum).getId();
- if (segmentNum == stationNum) {
- probas.put(stationId, this.config.SAME_STATION_DETECTION_CHANCE);
- } else {
- probas.put(stationId, this.config.BASE_DETECTION_CHANCE);
- }
- }
- emissionProbabilities.put(segmentNum, probas);
- }
-
- // ************************************
- // Build transition probability mapping
- // ************************************
- Map> transitionProbabilities = new HashMap<>();
- for (int prevSegment = 0; prevSegment < stations.size(); prevSegment++) {
- Map probas = new HashMap<>();
-
- // a station is skipped when it is broken, or when all detections are missed
- // TODO: this currently does not take into account detections by other stations
- double skipStationProbability = this.config.BROKEN_STATION_PROBABILITY + Math.pow(
- 1 - this.config.SAME_STATION_DETECTION_CHANCE,
- this.config.EXPECTED_NUM_DETECTIONS
- );
-
- // calculate amount of steps this way so that backwards steps are rounded down
- // and forward steps is rounded up (because we'd like to assume people run in the right direction)
- int numStepsBackwards = (stations.size() - 1) / 2;
- int numStepsForwards = stations.size() - 1 - numStepsBackwards;
-
- // This represents the odds (sameStationWeight against one) of staying on the same station
- // "how much more likely is it to stay, compared to moving"
- double sameStationWeight = (1 - this.config.BROKEN_STATION_PROBABILITY) * this.config.EXPECTED_NUM_DETECTIONS;
- // add 2: one unit of weight for running forwards, one for running backwards
- probas.put(prevSegment, sameStationWeight / (sameStationWeight + 2));
-
- // transition probabilities for running forwards.
- // To be precise: these probabilities should represent the probability that you will be at nextSegment
- // when the next detection happens. So assuming that you cannot be detected when you are in segment 2,
- // the transition probabilities towards segment 2 should always be 0.
- // This is because the viterbi algorithm runs in discrete time-steps, where each step corresponds
- // to a single detection (and is only vaguely related to the passage of time or distance).
- double remainingProbabilityMass = 1 / (sameStationWeight + 2);
- for (int i = 1; i <= numStepsForwards; i++) {
- // compute next segment index
- int nextSegment = Math.floorMod(prevSegment + i, stations.size());
- double proba = remainingProbabilityMass;
- if (i < numStepsForwards) {
- // multiply by the probability that this station was not skipped.
- // When this is the final step, we do not consider the possibility of skipping anymore
- // (so that probabilities add up to 1)
- proba *= (1 - skipStationProbability);
- }
- probas.put(nextSegment, proba);
-
- // subtract the used amount of probability mass
- remainingProbabilityMass -= proba;
- }
-
- // transition probabilities for running backwards
- // refer to above comments
- remainingProbabilityMass = 1 / (sameStationWeight + 2);
- for (int i = 1; i <= numStepsBackwards; i++) {
- int nextSegment = Math.floorMod(prevSegment - i, stations.size());
- double proba = remainingProbabilityMass;
- if (i < numStepsBackwards) {
- proba *= (1 - skipStationProbability);
- }
- probas.put(nextSegment, proba);
- remainingProbabilityMass -= proba;
- }
-
- transitionProbabilities.put(prevSegment, probas);
- }
-
- return new ViterbiModel<>(
- stations.stream().map(Station::getId).collect(Collectors.toSet()),
- IntStream.range(0, stations.size()).boxed().collect(Collectors.toSet()),
- transitionProbabilities,
- emissionProbabilities,
- calculateStartProbabilities()
- );
- }
-
- public Map> getProbabilities() {
- Map> ret = new HashMap<>();
- for (Map.Entry entry : this.currentStates.entrySet()) {
- ret.put(entry.getKey(), entry.getValue().probabilities());
- }
- return ret;
- }
-
- public Map>> getLapTimes() {
- Map>> ret = new HashMap<>();
- for (Map.Entry entry : this.currentStates.entrySet()) {
- ret.put(entry.getKey(), entry.getValue().lapTimestamps());
- }
- return ret;
- }
-
- private Map calculateStartProbabilities() {
- StationDAO stationDAO = jdbi.onDemand(StationDAO.class);
- List stations = stationDAO.getAll();
- int numStations = stations.size();
-
- Map ret = new HashMap<>();
-
- ret.put(0, 1.0 - (numStations - 1) * this.config.RESTART_PROBABILITY);
- for (int i = 1; i < numStations; i++) {
- ret.put(i, this.config.RESTART_PROBABILITY);
- }
-
- return ret;
- }
-
- @Override
- public synchronized void handle(Detection msg) {
- if (msg.getRssi() < -77) {
- return;
- }
- if (!this.debounceScheduled) {
- // TODO: this might be better as an atomic
- this.debounceScheduled = true;
- this.scheduler.schedule(() -> {
- try {
- this.calculateLaps();
- } catch (Exception e) {
- logger.severe(e.getMessage());
- }
- this.debounceScheduled = false;
- }, this.config.DEBOUNCE_TIMEOUT, TimeUnit.SECONDS);
- }
- }
-
- public synchronized void calculateLaps() {
- System.out.println("Calculating laps");
-
- TeamDAO teamDAO = this.jdbi.onDemand(TeamDAO.class);
- DetectionDAO detectionDAO = this.jdbi.onDemand(DetectionDAO.class);
- LapDAO lapDAO = this.jdbi.onDemand(LapDAO.class);
- BatonSwitchoverDAO batonSwitchoverDAO = this.jdbi.onDemand(BatonSwitchoverDAO.class);
- LapSourceSwitchoverDAO lapSourceSwitchoverDAO = this.jdbi.onDemand(LapSourceSwitchoverDAO.class);
- List teams = teamDAO.getAll();
- List switchovers = batonSwitchoverDAO.getAll();
-
- Optional maybeFirstLapSourceSwitchover = lapSourceSwitchoverDAO.getAll().stream().filter((x) -> x.getNewLapSource() == 3).findFirst();
- Timestamp firstSwitchover = maybeFirstLapSourceSwitchover.map(LapSourceSwitchover::getTimestamp).orElse(new Timestamp(0));
-
- // TODO: stream these from the database
- List detections = detectionDAO.getAll();
- detections.removeIf((detection) -> detection.getRssi() < -77 || detection.getTimestamp().before(firstSwitchover));
- detections.sort(Comparator.comparing(Detection::getTimestamp));
-
- // we create a viterbi model each time because the set of stations is not static
- ViterbiModel viterbiModel = createViterbiModel();
-
- Map> viterbis = teams.stream()
- .collect(Collectors.toMap(Team::getId, _team -> new ViterbiAlgorithm<>(viterbiModel)));
-
- Map batonIdToTeamId = new HashMap<>();
-
- int switchoverIndex = 0;
-
- for (Detection detection : detections) {
- while (switchoverIndex < switchovers.size() && switchovers.get(switchoverIndex).getTimestamp().before(detection.getTimestamp())) {
- BatonSwitchover switchover = switchovers.get(switchoverIndex);
- batonIdToTeamId.put(switchover.getNewBatonId(), switchover.getTeamId());
- switchoverIndex += 1;
- }
-
- if (batonIdToTeamId.containsKey(detection.getBatonId())) {
- int teamId = batonIdToTeamId.get(detection.getBatonId());
- viterbis.get(teamId).observe(detection.getStationId(), detection.getTimestamp());
- }
- }
-
- this.currentStates = viterbis.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().getState()));
-
- // We made a new estimation of the lap count, now we can update the database state to match
-
- Map> lapsByTeam = teams.stream().collect(Collectors.toMap(Team::getId, x -> new TreeSet<>(Comparator.comparing(Lap::getTimestamp))));
-
- for (Lap lap : lapDAO.getAllBySource(this.lapSourceId)) {
- lapsByTeam.get(lap.getTeamId()).add(lap);
- }
-
- for (Map.Entry entry : this.currentStates.entrySet()) {
- int teamId = entry.getKey();
- TreeSet laps = lapsByTeam.get(teamId);
-
- ViterbiState state = entry.getValue();
-
- Set currentLaps = laps.stream().map(Lap::getTimestamp).collect(Collectors.toSet());
- Set predictedLaps = state.lapTimestamps().get(state.mostLikelySegment());
-
- Set toRemove = new TreeSet<>(currentLaps);
- toRemove.removeAll(predictedLaps);
-
- Set toAdd = new TreeSet<>(predictedLaps);
- toAdd.removeAll(currentLaps);
-
- for (Timestamp timestamp : toRemove) {
- lapDAO.removeByTeamAndTimestamp(teamId, timestamp);
- }
-
- for (Timestamp timestamp : toAdd) {
- lapDAO.insert(new Lap(teamId, this.lapSourceId, timestamp));
- }
- }
-
- System.out.println("Done calculating laps");
- }
-
- @Override
- public void registerAPI(JerseyEnvironment jersey) {
- jersey.register(new ViterbiLapperResource(this));
- }
-
- public ViterbiLapperConfiguration getConfig() {
- return this.config;
- }
-
- public ViterbiModel getModel() {
- return this.createViterbiModel();
- }
-}
diff --git a/src/main/java/telraam/logic/viterbi/ViterbiLapperConfiguration.java b/src/main/java/telraam/logic/viterbi/ViterbiLapperConfiguration.java
deleted file mode 100644
index 0c1c8ce..0000000
--- a/src/main/java/telraam/logic/viterbi/ViterbiLapperConfiguration.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package telraam.logic.viterbi;
-
-public class ViterbiLapperConfiguration {
- public double RESTART_PROBABILITY; // The probability that the runners will start the race in a different spot than the start/finish line (should only happen on complete restarts)
- public int DEBOUNCE_TIMEOUT; // The amount of time detections are debounced for in seconds
-
- // probability that you will be for detection in the segment corresponding to a station
- public double SAME_STATION_DETECTION_CHANCE;
-
- // the probability that you will be detected at a random station ("noise" detections)
- public double BASE_DETECTION_CHANCE;
-
- // the probability that an individual station is down at any moment in time
- // ~= downtime / total time.
- // It is not that important that this parameter is estimated correctly (which would be very hard to do)
- // it is better to interpret this as the system's eagerness to assume that a station was not working
- // when trying to explain a series of detections.
- public double BROKEN_STATION_PROBABILITY;
-
- // The amount of times we expect a runner to be detected when passing by a station, given that the station is alive.
- //
- // The higher this parameter, the more 'evidence' (= detections) the system will require
- // in order to change the predicted location - so, the predictions will be less sensitive to noise detections
- // at different stations.
- // Consequently, it is better to under-estimate this parameter than to over-estimate it.
- public double EXPECTED_NUM_DETECTIONS;
-
- public ViterbiLapperConfiguration() {
- this.RESTART_PROBABILITY = 0.001;
- this.DEBOUNCE_TIMEOUT = 10;
-
- // ballpark estimates extracted from test event data
- // IMPORTANT: these numbers are only valid assuming that detection are filtered for rssi >=-70
- // (ask @iasoon for details)
- this.SAME_STATION_DETECTION_CHANCE = 0.90;
- this.BASE_DETECTION_CHANCE = 0.10;
- this.EXPECTED_NUM_DETECTIONS = 3;
-
-
- this.BROKEN_STATION_PROBABILITY = 0.01;
- }
-}
diff --git a/src/main/java/telraam/logic/viterbi/ViterbiLapperResource.java b/src/main/java/telraam/logic/viterbi/ViterbiLapperResource.java
deleted file mode 100644
index 3b1de23..0000000
--- a/src/main/java/telraam/logic/viterbi/ViterbiLapperResource.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package telraam.logic.viterbi;
-
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import telraam.logic.viterbi.algorithm.ViterbiModel;
-
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import java.sql.Timestamp;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-@Path("/lappers/viterbi")
-@Api("/lappers/viterbi")
-@Produces(MediaType.APPLICATION_JSON)
-public class ViterbiLapperResource {
- private final ViterbiLapper lapper;
-
- public ViterbiLapperResource(ViterbiLapper lapper) {
- this.lapper = lapper;
- }
-
- @GET
- @Path("/probabilities")
- @ApiOperation(value = "Get lapper position probabilities")
- public Map> getProbabilities() {
- return this.lapper.getProbabilities();
- }
-
- @GET
- @Path("/lap-times")
- @ApiOperation(value = "Get lapper estimated laps")
- public Map>> getLapTimes() {
- return this.lapper.getLapTimes();
- }
-
- @GET
- @Path("/configuration")
- @ApiOperation(value = "Get lapper configuration")
- public ViterbiLapperConfiguration getConfiguration() {
- return this.lapper.getConfig();
- }
-
- @GET
- @Path("/model")
- @ApiOperation(value = "Get Viterbi model")
- public ViterbiModel getModel() {
- return this.lapper.getModel();
- }
-
- @GET
- @Path("/recalculate")
- @ApiOperation(value = "Recalculate Viterbi rounds")
- public String recalculateRounds() {
- this.lapper.calculateLaps();
- return "Recalculated rounds";
- }
-}
diff --git a/src/main/java/telraam/logic/viterbi/algorithm/InvalidParameterException.java b/src/main/java/telraam/logic/viterbi/algorithm/InvalidParameterException.java
deleted file mode 100644
index 632bf2d..0000000
--- a/src/main/java/telraam/logic/viterbi/algorithm/InvalidParameterException.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package telraam.logic.viterbi.algorithm;
-
-public class InvalidParameterException extends RuntimeException {
- public InvalidParameterException(String s) {
- super(s);
- }
-}
diff --git a/src/main/java/telraam/logic/viterbi/algorithm/ViterbiAlgorithm.java b/src/main/java/telraam/logic/viterbi/algorithm/ViterbiAlgorithm.java
deleted file mode 100644
index 2f4e82f..0000000
--- a/src/main/java/telraam/logic/viterbi/algorithm/ViterbiAlgorithm.java
+++ /dev/null
@@ -1,127 +0,0 @@
-package telraam.logic.viterbi.algorithm;
-
-import io.swagger.models.auth.In;
-
-import java.sql.Time;
-import java.sql.Timestamp;
-import java.util.*;
-
-/**
- * The class performing the Viterbi algorithm.
- * @param The type of the observations.
- */
-public class ViterbiAlgorithm {
- private final ViterbiModel model;
-
- private ViterbiState lastState;
-
- public ViterbiAlgorithm(ViterbiModel viterbiModel) {
- this.model = viterbiModel;
-
- this.verifyProbabilities();
-
- // Set up the initial probabilities
- int numSegments = this.model.getHiddenStates().size();
- Map probabilities = new HashMap<>();
- Map previousSegments = new HashMap<>();
- Map> lapTimestamps = new HashMap<>();
-
- for (Map.Entry entry : viterbiModel.getStartProbabilities().entrySet()) {
- probabilities.put(entry.getKey(), entry.getValue());
- previousSegments.put(entry.getKey(), 0);
- lapTimestamps.put(entry.getKey(), new TreeSet<>());
- }
-
- this.lastState = new ViterbiState(probabilities, previousSegments, lapTimestamps);
- }
-
- /**
- * Verify that the given probabilities are valid.
- * @throws InvalidParameterException If the probabilities were not valid.
- */
- private void verifyProbabilities() {
- if (!this.model.getTransitionProbabilities().keySet().equals(this.model.getHiddenStates())) {
- throw new InvalidParameterException("Invalid key set for transition probabilities");
- }
-
- for (Integer state : this.model.getHiddenStates()) {
- if (!this.model.getTransitionProbabilities().get(state).keySet().equals(this.model.getHiddenStates())) {
- throw new InvalidParameterException("Invalid key set for transition probabilities for state " + state);
- }
- }
-
- if (!this.model.getEmitProbabilities().keySet().equals(this.model.getHiddenStates())) {
- throw new InvalidParameterException("Invalid key set for emission probabilities: " + this.model.getEmitProbabilities().keySet() + " != " + this.model.getHiddenStates());
- }
-
- for (Integer state : this.model.getHiddenStates()) {
- if (!this.model.getTransitionProbabilities().get(state).keySet().equals(this.model.getHiddenStates())) {
- throw new InvalidParameterException(
- "Invalid key set for emission probabilities for state " +
- state +
- ": " +
- this.model.getTransitionProbabilities().get(state).keySet() +
- " != " +
- this.model.getObservations()
- );
- }
- }
- }
-
- /**
- * Handle an observation.
- * @param observation The observation to process.
- * @param observationTimestamp The timestamp when this observation was made
- */
- public void observe(O observation, Timestamp observationTimestamp) {
- int numSegments = this.model.getHiddenStates().size();
- Map probabilities = new HashMap<>();
- Map previousSegments = new HashMap<>();
- Map> lapTimestamps = new HashMap<>();
-
- for (int nextSegment = 0; nextSegment < numSegments; nextSegment++) {
- probabilities.put(nextSegment, 0.0);
- for (int previousSegment = 0; previousSegment < numSegments; previousSegment++) {
- double probability = this.lastState.probabilities().get(previousSegment) *
- this.model.getTransitionProbabilities().get(previousSegment).get(nextSegment) *
- this.model.getEmitProbabilities().get(nextSegment).get(observation);
- if (probabilities.get(nextSegment) < probability) {
- probabilities.put(nextSegment, probability);
- previousSegments.put(nextSegment, previousSegment);
-
- int half = numSegments / 2;
- // Dit is het algoritme van De Voerstreek
- int delta = half - (half - (nextSegment - previousSegment)) % numSegments;
-
- Set newTimestamps = new TreeSet<>(this.lastState.lapTimestamps().get(previousSegment));
-
- if (delta > 0 && previousSegment > nextSegment) {
- // forward wrap-around
- newTimestamps.add(observationTimestamp);
- } else if (delta < 0 && previousSegment < nextSegment) {
- // backwards wrap-around
- Optional highestTimestamp = newTimestamps.stream().max(Timestamp::compareTo);
- highestTimestamp.ifPresent(newTimestamps::remove);
- }
- lapTimestamps.put(nextSegment, newTimestamps);
- }
- }
- }
-
- // normalize probabilities
- double sum = probabilities.values().stream().reduce(0.0, Double::sum);
- for (int i = 0; i < numSegments; i++) {
- probabilities.put(i, probabilities.get(i) / sum);
- }
-
- this.lastState = new ViterbiState(probabilities, previousSegments, lapTimestamps);
- }
-
- /**
- * Get the current state of the Viterbi algorithm.
- * @return The last Result.
- */
- public ViterbiState getState() {
- return this.lastState;
- }
-}
diff --git a/src/main/java/telraam/logic/viterbi/algorithm/ViterbiModel.java b/src/main/java/telraam/logic/viterbi/algorithm/ViterbiModel.java
deleted file mode 100644
index edda291..0000000
--- a/src/main/java/telraam/logic/viterbi/algorithm/ViterbiModel.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package telraam.logic.viterbi.algorithm;
-
-import java.util.Map;
-import java.util.Set;
-
-public record ViterbiModel(Set observations, Set hiddenStates,
- Map> transitionProbabilities,
- Map> emitProbabilities,
- Map startProbabilities) {
-
- public Set getObservations() {
- return observations;
- }
-
- public Set getHiddenStates() {
- return hiddenStates;
- }
-
- public Map> getTransitionProbabilities() {
- return transitionProbabilities;
- }
-
- public Map> getEmitProbabilities() {
- return emitProbabilities;
- }
-
- public Map getStartProbabilities() {
- return startProbabilities;
- }
-}
diff --git a/src/main/java/telraam/logic/viterbi/algorithm/ViterbiState.java b/src/main/java/telraam/logic/viterbi/algorithm/ViterbiState.java
deleted file mode 100644
index ada5d6b..0000000
--- a/src/main/java/telraam/logic/viterbi/algorithm/ViterbiState.java
+++ /dev/null
@@ -1,25 +0,0 @@
-package telraam.logic.viterbi.algorithm;
-
-import java.sql.Timestamp;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Helper class to store steps in the Viterbi algorithm.
- */
-public record ViterbiState(Map probabilities, Map previousStates, Map> lapTimestamps) {
- /**
- * Get the most likely state to be in, in this Result
- *
- * @return The state that is most likely.
- */
- public Integer mostLikelySegment() {
- int mostLikelySegment = 0;
- for (int i : probabilities.keySet()) {
- if (this.probabilities.get(i) > this.probabilities.get(mostLikelySegment)) {
- mostLikelySegment = i;
- }
- }
- return mostLikelySegment;
- }
-}
diff --git a/src/main/java/telraam/station/Fetcher.java b/src/main/java/telraam/station/Fetcher.java
index cf371f8..54e04db 100644
--- a/src/main/java/telraam/station/Fetcher.java
+++ b/src/main/java/telraam/station/Fetcher.java
@@ -8,6 +8,8 @@
import telraam.database.models.Detection;
import telraam.database.models.Station;
import telraam.logic.Lapper;
+import telraam.station.models.RonnyDetection;
+import telraam.station.models.RonnyResponse;
import java.io.IOException;
import java.net.ConnectException;
diff --git a/src/main/java/telraam/station/RonnyDetection.java b/src/main/java/telraam/station/models/RonnyDetection.java
similarity index 90%
rename from src/main/java/telraam/station/RonnyDetection.java
rename to src/main/java/telraam/station/models/RonnyDetection.java
index 40689b8..234a50d 100644
--- a/src/main/java/telraam/station/RonnyDetection.java
+++ b/src/main/java/telraam/station/models/RonnyDetection.java
@@ -1,4 +1,4 @@
-package telraam.station;
+package telraam.station.models;
import com.fasterxml.jackson.annotation.JsonProperty;
diff --git a/src/main/java/telraam/station/RonnyResponse.java b/src/main/java/telraam/station/models/RonnyResponse.java
similarity index 87%
rename from src/main/java/telraam/station/RonnyResponse.java
rename to src/main/java/telraam/station/models/RonnyResponse.java
index b2cf9ef..011f2c7 100644
--- a/src/main/java/telraam/station/RonnyResponse.java
+++ b/src/main/java/telraam/station/models/RonnyResponse.java
@@ -1,4 +1,4 @@
-package telraam.station;
+package telraam.station.models;
import java.util.List;
diff --git a/src/main/resources/banner.txt b/src/main/resources/banner.txt
index f11cd06..46bfca7 100644
--- a/src/main/resources/banner.txt
+++ b/src/main/resources/banner.txt
@@ -1 +1,8 @@
-ZeusWPI - Telraam
\ No newline at end of file
+
+
+ _____ __ ______ ___ _____ _
+|__ /___ _ _ ___ \ \ / / _ \_ _| |_ _|__| |_ __ __ _ __ _ _ __ ___
+ / // _ \ | | / __| \ \ /\ / /| |_) | | _____ | |/ _ \ | '__/ _` |/ _` | '_ ` _ \
+ / /| __/ |_| \__ \ \ V V / | __/| | |_____| | | __/ | | | (_| | (_| | | | | | |
+/____\___|\__,_|___/ \_/\_/ |_| |___| |_|\___|_|_| \__,_|\__,_|_| |_| |_|
+
diff --git a/src/test/java/telraam/logic/SimpleLapperTest.java b/src/test/java/telraam/logic/SimpleLapperTest.java
index 4214d13..7758c47 100644
--- a/src/test/java/telraam/logic/SimpleLapperTest.java
+++ b/src/test/java/telraam/logic/SimpleLapperTest.java
@@ -8,6 +8,7 @@
import telraam.database.models.Detection;
import telraam.database.models.Lap;
import telraam.database.models.LapSource;
+import telraam.logic.simple.SimpleLapper;
import java.sql.Timestamp;
import java.util.Optional;