Removed MovingAverage processor from polar data miner

Was only meant for comparison purposes with Regression. Now regression is
used every anyway, so we only need to have the regression processors
This commit is contained in:
Frederik Petersen committed 2015-07-20 17:41:54 +02:00
1 parent e25d10bddb
commit 071a23bc8f
12 files changed
+31 -193

No files matched your search

@@ -7,10 +7,6 @@ import com.sap.sse.common.Util.Pair;
public interface PolarSheetsXYDiagramData extends Serializable {
List<Pair<Double, Double>> getPointsForAverageSpeedMovingAverage(Tack tack, LegType legType);
List<Pair<Double, Double>> getPointsForAverageConfidence(Tack tack, LegType legType);
List<Pair<Double, Double>> getPointsForAverageSpeedRegression(Tack tack, LegType legType);
}
@@ -15,29 +15,11 @@ public class PolarSheetsXYDiagramDataImpl implements PolarSheetsXYDiagramData {
PolarSheetsXYDiagramDataImpl() {
}
private Map<Pair<LegType, Tack>, List<Pair<Double, Double>>> pointsForAverageSpeedMovingAverage;
private Map<Pair<LegType, Tack>, List<Pair<Double, Double>>> pointsForAverageSpeedRegression;
private Map<Pair<LegType, Tack>, List<Pair<Double, Double>>> pointsForAverageConfidence;
public PolarSheetsXYDiagramDataImpl(
Map<Pair<LegType, Tack>, List<Pair<Double, Double>>> movingAverageSpeedDataLists,
Map<Pair<LegType, Tack>, List<Pair<Double, Double>>> regressionSpeedDataLists,
Map<Pair<LegType, Tack>, List<Pair<Double, Double>>> averageConfidenceDataLists) {
pointsForAverageSpeedMovingAverage = movingAverageSpeedDataLists;
Map<Pair<LegType, Tack>, List<Pair<Double, Double>>> regressionSpeedDataLists) {
pointsForAverageSpeedRegression = regressionSpeedDataLists;
pointsForAverageConfidence = averageConfidenceDataLists;
}
@Override
public List<Pair<Double, Double>> getPointsForAverageSpeedMovingAverage(Tack tack, LegType legType) {
return pointsForAverageSpeedMovingAverage.get(new Pair<LegType, Tack>(legType, tack));
}
@Override
public List<Pair<Double, Double>> getPointsForAverageConfidence(Tack tack, LegType legType) {
return pointsForAverageConfidence.get(new Pair<LegType, Tack>(legType, tack));
}
@Override
@@ -52,36 +52,6 @@ public interface PolarDataService {
SpeedWithConfidence<Void> getSpeed(BoatClass boatClass, Speed windSpeed, Bearing trueWindAngle)
throws NotEnoughDataHasBeenAddedException;
/**
*
* @param boatClass
* @param windSpeed
* @param legType
* Should be {@link LegType#UPWIND} or {@link LegType#DOWNWIND}, there is no information for other
* courses yet. Use getSpeed for the desired angle to get rawer information on other courses for now.
* @param tack
* Polar data can vary depending on the tack the boat is on.
* @param useRegressionForSpeed TODO
* @return The estimated average speed of a boat for the supplied parameters with the estimated average bearing to
* the true wind and a confidence which consists of the confidences of the wind speed, and boat speed sources (50%)
* and a confidence calculated using the amount of underlying fixes (50%). 0 <= confidence < 1<br/>
* A value with zero confidence doesn't have any significance!<br/>
* <br/>
*
* The bearing is somewhere between -179 to +180<br/>
* <br/>
*
* Get the speed using returnValue.getObject()<br/>
* <br/>
*
* Returns null if the leg type is not up or downwind.
*
* @throws NotEnoughDataHasBeenAddedException
* If there is not enough data to supply a value with some kind of significance.
*/
SpeedWithBearingWithConfidence<Void> getAverageSpeedWithBearing(BoatClass boatClass, Speed windSpeed,
LegType legType, Tack tack, boolean useRegressionForSpeed) throws NotEnoughDataHasBeenAddedException;
/**
* Generates a polar sheet for given races and settings using the provided executor for the worker threads. This
@@ -4,12 +4,9 @@ import java.util.List;
import org.moxieapps.gwt.highcharts.client.AxisTitle;
import org.moxieapps.gwt.highcharts.client.Chart;
import org.moxieapps.gwt.highcharts.client.PlotLine;
import org.moxieapps.gwt.highcharts.client.Point;
import org.moxieapps.gwt.highcharts.client.Series;
import org.moxieapps.gwt.highcharts.client.Series.Type;
import org.moxieapps.gwt.highcharts.client.plotOptions.Marker;
import org.moxieapps.gwt.highcharts.client.plotOptions.SplinePlotOptions;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
@@ -58,33 +55,14 @@ public class PolarSheetsXYDiagramPopupPanel extends DialogBox {
}
private void addSpeedAndConfidenceSeriesForTackAndLegType(PolarSheetsXYDiagramData result, Tack tack, LegType legType, boolean showByDefault) {
Point[] pointsForUpwindStarboardAverageSpeedMovingAverage = toPointArray(result.getPointsForAverageSpeedMovingAverage(tack, legType));
Series speedSeriesMovingAverage = chart.createSeries();
speedSeriesMovingAverage.setName(tack + " " + legType + " Speed - MovingAverage");
speedSeriesMovingAverage.setPoints(pointsForUpwindStarboardAverageSpeedMovingAverage);
chart.addSeries(speedSeriesMovingAverage, false, false);
Point[] pointsForUpwindStarboardAverageSpeedRegression = toPointArray(result.getPointsForAverageSpeedRegression(tack, legType));
Series speedSeriesRegression = chart.createSeries();
speedSeriesRegression.setName(tack + " " + legType + " Speed - Regression");
speedSeriesRegression.setPoints(pointsForUpwindStarboardAverageSpeedRegression);
chart.addSeries(speedSeriesRegression, false, false);
Point[] pointsForUpwindStarboardAverageConfidence = toPointArray(result.getPointsForAverageConfidence(tack, legType));
Series confidenceSeries = chart
.createSeries()
.setYAxis(1)
.setType(Series.Type.SPLINE)
.setPlotOptions(
new SplinePlotOptions().setColor("#AA4643").setMarker(new Marker().setEnabled(false))
.setDashStyle(PlotLine.DashStyle.SHORT_DOT));
confidenceSeries.setName(tack + " " + legType + " Confidence");
confidenceSeries.setPoints(pointsForUpwindStarboardAverageConfidence);
chart.addSeries(confidenceSeries, false, false);
if (!showByDefault) {
speedSeriesRegression.setVisible(false, false);
confidenceSeries.setVisible(false, false);
}
}
@@ -61,10 +61,10 @@ import com.sap.sailing.domain.abstractlog.AbstractLog;
import com.sap.sailing.domain.abstractlog.AbstractLogEvent;
import com.sap.sailing.domain.abstractlog.MultiLogAnalyzer;
import com.sap.sailing.domain.abstractlog.impl.AllEventsOfTypeFinder;
import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLog;
import com.sap.sailing.domain.abstractlog.race.RaceLogEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogEventFactory;
import com.sap.sailing.domain.abstractlog.race.RaceLogFixedMarkPassingEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogFlagEvent;
import com.sap.sailing.domain.abstractlog.race.RaceLogSuppressedMarkPassingsEvent;
import com.sap.sailing.domain.abstractlog.race.analyzing.impl.AbortingFlagFinder;
@@ -5585,45 +5585,20 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
@Override
public PolarSheetsXYDiagramData createXYDiagramForBoatClass(String boatClassName) {
BoatClass boatClass = getService().getBaseDomainFactory().getOrCreateBoatClass(boatClassName);
Map<Pair<LegType, Tack>, List<Pair<Double, Double>>> movingAverageSpeedDataLists = new HashMap<>();
Map<Pair<LegType, Tack>, List<Pair<Double, Double>>> regressionSpeedDataLists = new HashMap<>();
Map<Pair<LegType, Tack>, List<Pair<Double, Double>>> averageConfidenceDataLists = new HashMap<>();
for (LegType legType : new LegType[] { LegType.UPWIND, LegType.DOWNWIND }) {
for (Tack tack : new Tack[] { Tack.PORT, Tack.STARBOARD }) {
movingAverageSpeedDataLists.put(new Pair<LegType, Tack>(legType, tack),
new ArrayList<Pair<Double, Double>>());
regressionSpeedDataLists.put(new Pair<LegType, Tack>(legType, tack),
new ArrayList<Pair<Double, Double>>());
averageConfidenceDataLists.put(new Pair<LegType, Tack>(legType, tack),
new ArrayList<Pair<Double, Double>>());
}
}
for (double windInKnots = 0.1; windInKnots < 30; windInKnots = windInKnots + 0.1) {
for (LegType legType : new LegType[] { LegType.UPWIND, LegType.DOWNWIND }) {
for (Tack tack : new Tack[] { Tack.PORT, Tack.STARBOARD }) {
try {
SpeedWithBearingWithConfidence<Void> averageUpwindStarboardMovingAverage = getService()
.getPolarDataService().getAverageSpeedWithBearing(boatClass,
new KnotSpeedImpl(windInKnots), legType, tack, false);
movingAverageSpeedDataLists.get(new Pair<LegType, Tack>(legType, tack)).add(
new Pair<Double, Double>(windInKnots, averageUpwindStarboardMovingAverage.getObject()
.getKnots()));
averageConfidenceDataLists.get(new Pair<LegType, Tack>(legType, tack)).add(
new Pair<Double, Double>(windInKnots, averageUpwindStarboardMovingAverage
.getConfidence()));
} catch (NotEnoughDataHasBeenAddedException e) {
// Do not add a point to the result
}
try {
SpeedWithBearingWithConfidence<Void> averageUpwindStarboardRegression = getService()
.getPolarDataService().getAverageSpeedWithBearing(boatClass,
new KnotSpeedImpl(windInKnots), legType, tack, true);
new KnotSpeedImpl(windInKnots), legType, tack);
regressionSpeedDataLists.get(new Pair<LegType, Tack>(legType, tack)).add(
new Pair<Double, Double>(windInKnots, averageUpwindStarboardRegression.getObject()
@@ -5635,8 +5610,7 @@ public class SailingServiceImpl extends ProxiedRemoteServiceServlet implements S
}
}
PolarSheetsXYDiagramData data = new PolarSheetsXYDiagramDataImpl(movingAverageSpeedDataLists,
regressionSpeedDataLists, averageConfidenceDataLists);
PolarSheetsXYDiagramData data = new PolarSheetsXYDiagramDataImpl(regressionSpeedDataLists);
return data;
}
@@ -32,7 +32,6 @@ import com.sap.sailing.domain.base.Waypoint;
import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.PolarSheetGenerationSettings;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.common.SpeedWithBearing;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
@@ -52,9 +51,7 @@ import com.sap.sailing.domain.tracking.impl.DynamicGPSFixMovingTrackImpl;
import com.sap.sailing.domain.tracking.impl.WindWithConfidenceImpl;
import com.sap.sailing.polars.mining.BearingClusterGroup;
import com.sap.sailing.polars.mining.CubicRegressionPerCourseProcessor;
import com.sap.sailing.polars.mining.MovingAverageProcessorImpl;
import com.sap.sailing.polars.mining.PolarDataMiner;
import com.sap.sailing.polars.mining.SpeedClusterGroupFromWindSteppingCreator;
import com.sap.sailing.polars.mining.SpeedRegressionPerAngleClusterProcessor;
import com.sap.sse.common.TimePoint;
import com.sap.sse.common.Util.Pair;
@@ -91,12 +88,9 @@ public class PolarDataMinerTest {
NotEnoughDataHasBeenAddedException {
PolarSheetGenerationSettings settings = createTestPolarSettings();
ClusterGroup<Bearing> angleClusterGroup = createAngleClusterGroup();
WindSpeedSteppingWithMaxDistance stepping = settings.getWindSpeedStepping();
final ClusterGroup<Speed> speedClusterGroup = SpeedClusterGroupFromWindSteppingCreator
.createSpeedClusterGroupFrom(stepping);
PolarDataMiner miner = new PolarDataMiner(settings, new MovingAverageProcessorImpl(speedClusterGroup),
PolarDataMiner miner = new PolarDataMiner(settings,
new CubicRegressionPerCourseProcessor(),
new SpeedRegressionPerAngleClusterProcessor(angleClusterGroup), speedClusterGroup, angleClusterGroup);
new SpeedRegressionPerAngleClusterProcessor(angleClusterGroup), angleClusterGroup);
BoatClass mockedBoatClass = mock(BoatClass.class);
@@ -33,7 +33,6 @@ import com.sap.sailing.domain.common.confidence.impl.BearingWithConfidenceImpl;
import com.sap.sailing.domain.common.impl.DegreeBearingImpl;
import com.sap.sailing.domain.common.impl.KnotSpeedWithBearingImpl;
import com.sap.sailing.domain.common.impl.PolarSheetGenerationSettingsImpl;
import com.sap.sailing.domain.common.impl.WindSpeedSteppingWithMaxDistance;
import com.sap.sailing.domain.common.tracking.GPSFixMoving;
import com.sap.sailing.domain.polars.NotEnoughDataHasBeenAddedException;
import com.sap.sailing.domain.polars.PolarDataService;
@@ -46,9 +45,7 @@ import com.sap.sailing.polars.data.PolarFix;
import com.sap.sailing.polars.generation.PolarSheetGenerator;
import com.sap.sailing.polars.mining.BearingClusterGroup;
import com.sap.sailing.polars.mining.CubicRegressionPerCourseProcessor;
import com.sap.sailing.polars.mining.MovingAverageProcessorImpl;
import com.sap.sailing.polars.mining.PolarDataMiner;
import com.sap.sailing.polars.mining.SpeedClusterGroupFromWindSteppingCreator;
import com.sap.sailing.polars.mining.SpeedRegressionPerAngleClusterProcessor;
import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.data.ClusterGroup;
@@ -91,15 +88,11 @@ public class PolarDataServiceImpl implements PolarDataService, ReplicableWithObj
public PolarDataServiceImpl() {
PolarSheetGenerationSettings settings = PolarSheetGenerationSettingsImpl.createBackendPolarSettings();
ClusterGroup<Bearing> angleClusterGroup = createAngleClusterGroup();
WindSpeedSteppingWithMaxDistance stepping = settings.getWindSpeedStepping();
final ClusterGroup<Speed> speedClusterGroup = SpeedClusterGroupFromWindSteppingCreator
.createSpeedClusterGroupFrom(stepping);
MovingAverageProcessorImpl movingAverageProcessor = new MovingAverageProcessorImpl(speedClusterGroup);
CubicRegressionPerCourseProcessor cubicRegressionPerCourseProcessor = new CubicRegressionPerCourseProcessor();
SpeedRegressionPerAngleClusterProcessor speedRegressionPerAngleClusterProcessor = new SpeedRegressionPerAngleClusterProcessor(
angleClusterGroup);
this.polarDataMiner = new PolarDataMiner(settings, movingAverageProcessor, cubicRegressionPerCourseProcessor,
speedRegressionPerAngleClusterProcessor, speedClusterGroup, angleClusterGroup);
this.polarDataMiner = new PolarDataMiner(settings, cubicRegressionPerCourseProcessor,
speedRegressionPerAngleClusterProcessor, angleClusterGroup);
this.operationsSentToMasterForReplication = new HashSet<>();
this.operationExecutionListeners = new ConcurrentHashMap<>();
}
@@ -124,12 +117,12 @@ public class PolarDataServiceImpl implements PolarDataService, ReplicableWithObj
@Override
public SpeedWithBearingWithConfidence<Void> getAverageSpeedWithBearing(BoatClass boatClass, Speed windSpeed,
LegType legType, Tack tack, boolean useRegressionForSpeed) throws NotEnoughDataHasBeenAddedException {
LegType legType, Tack tack) throws NotEnoughDataHasBeenAddedException {
if (polarDataMiner == null) {
throw new NotEnoughDataHasBeenAddedException("Polar Data Miner is currently unavailable. Maybe we are in the process of replication initial load?");
}
SpeedWithBearingWithConfidence<Void> averageSpeedAndCourseOverGround = polarDataMiner
.getAverageSpeedAndCourseOverGround(boatClass, windSpeed, legType, useRegressionForSpeed);
.getAverageSpeedAndCourseOverGround(boatClass, windSpeed, legType);
if (tack == Tack.PORT) {
//Negative twa
DegreeBearingImpl bearing = new DegreeBearingImpl(-averageSpeedAndCourseOverGround.getObject().getBearing()
@@ -251,19 +244,13 @@ public class PolarDataServiceImpl implements PolarDataService, ReplicableWithObj
if (polarDataMiner == null) {
throw new NotEnoughDataHasBeenAddedException("Polar Data Miner is currently unavailable. Maybe we are in the process of replication initial load?");
}
SpeedWithBearingWithConfidence<Void> speed = polarDataMiner.getAverageSpeedAndCourseOverGround(boatClass, windSpeed, legType, true);
SpeedWithBearingWithConfidence<Void> speed = polarDataMiner.getAverageSpeedAndCourseOverGround(boatClass, windSpeed, legType);
Bearing bearing = new DegreeBearingImpl(speed.getObject().getBearing().getDegrees() * 2);
BearingWithConfidence<Void> bearingWithConfidence = new BearingWithConfidenceImpl<Void>(bearing, speed.getConfidence(),
null);
return bearingWithConfidence;
}
@Override
public SpeedWithBearingWithConfidence<Void> getAverageSpeedWithBearing(BoatClass boatClass, Speed windSpeed,
LegType legType, Tack tack) throws NotEnoughDataHasBeenAddedException {
return getAverageSpeedWithBearing(boatClass, windSpeed, legType, tack, true);
}
@Override
public void insertExistingFixes(TrackedRace trackedRace) {
for (Competitor competitor : trackedRace.getRace().getCompetitors()) {
@@ -331,19 +318,13 @@ public class PolarDataServiceImpl implements PolarDataService, ReplicableWithObj
public void initiallyFillFromInternal(ObjectInputStream is) throws IOException, ClassNotFoundException,
InterruptedException {
PolarSheetGenerationSettings backendPolarSettings = (PolarSheetGenerationSettings) is.readObject();
//MovingAverageProcessor movingAverageProcessor = (MovingAverageProcessor) is.readObject();
PolarSheetGenerationSettings settings = PolarSheetGenerationSettingsImpl.createBackendPolarSettings();
WindSpeedSteppingWithMaxDistance stepping = settings.getWindSpeedStepping();
final ClusterGroup<Speed> speedClusterGroup = SpeedClusterGroupFromWindSteppingCreator
.createSpeedClusterGroupFrom(stepping);
MovingAverageProcessorImpl movingAverageProcessor = new MovingAverageProcessorImpl(speedClusterGroup);
CubicRegressionPerCourseProcessor cubicRegressionPerCourseProcessor = (CubicRegressionPerCourseProcessor) is.readObject();
SpeedRegressionPerAngleClusterProcessor speedRegressionPerAngleClusterProcessor = (SpeedRegressionPerAngleClusterProcessor) is.readObject();
polarDataMiner = new PolarDataMiner(backendPolarSettings, movingAverageProcessor,
polarDataMiner = new PolarDataMiner(backendPolarSettings,
cubicRegressionPerCourseProcessor, speedRegressionPerAngleClusterProcessor,
movingAverageProcessor.getSpeedCluster(), speedRegressionPerAngleClusterProcessor.getAngleCluster());
speedRegressionPerAngleClusterProcessor.getAngleCluster());
}
@Override
@@ -10,7 +10,6 @@ import com.sap.sailing.domain.common.Bearing;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.Speed;
import com.sap.sailing.domain.common.WindSource;
import com.sap.sailing.domain.common.WindSourceType;
import com.sap.sailing.domain.common.confidence.BearingWithConfidence;
@@ -28,12 +27,11 @@ import com.sap.sse.common.Util.Pair;
import com.sap.sse.datamining.data.Cluster;
import com.sap.sse.datamining.data.ClusterGroup;
public class GPSFixMovingWithPolarContext implements MovingAveragePolarClusterKey, AngleClusterPolarClusterKey {
public class GPSFixMovingWithPolarContext implements LegTypePolarClusterKey, AngleClusterPolarClusterKey {
private final GPSFixMoving fix;
private final TrackedRace race;
private final Competitor competitor;
private final ClusterGroup<Speed> windSpeedClusterGroup;
private final Set<WindSource> windSourcesToExcludeForSpeed;
private final ClusterGroup<Bearing> angleClusterGroup;
private final BearingWithConfidence<Void> absTrueWindAngle;
@@ -42,11 +40,10 @@ public class GPSFixMovingWithPolarContext implements MovingAveragePolarClusterKe
private LegType legType;
public GPSFixMovingWithPolarContext(GPSFixMoving fix, TrackedRace race, Competitor competitor,
ClusterGroup<Speed> windSpeedClusterGroup, ClusterGroup<Bearing> angleClusterGroup) {
ClusterGroup<Bearing> angleClusterGroup) {
this.fix = fix;
this.race = race;
this.competitor = competitor;
this.windSpeedClusterGroup = windSpeedClusterGroup;
this.angleClusterGroup = angleClusterGroup;
this.windSourcesToExcludeForSpeed = collectWindSourcesToIgnoreForSpeed();
this.absTrueWindAngle = computeTrueWindAngleAbsolute();
@@ -89,12 +86,6 @@ public class GPSFixMovingWithPolarContext implements MovingAveragePolarClusterKe
return result;
}
@Override
public Cluster<Speed> getWindSpeedCluster() {
final WindWithConfidence<Pair<Position, TimePoint>> windWithConfidence = getWind();
return windWithConfidence == null ? null : windSpeedClusterGroup.getClusterFor(windWithConfidence.getObject());
}
public WindWithConfidence<Pair<Position, TimePoint>> getWind() {
return wind;
}
@@ -69,14 +69,8 @@ public class PolarDataMiner {
private ParallelFilteringProcessor<GPSFixMovingWithOriginInfo> preFilteringProcessor;
private final PolarSheetGenerationSettings backendPolarSheetGenerationSettings;
/**
* This processor keeps track of the moving average of the speed values and the average angle for each course (legtype tack combination)
*/
private final MovingAverageProcessor movingAverageProcessor;
/**
* This processor uses two cubic regressions angle to the true wind over windspeed and boatspeed over windspeed for each
* course (legtype tack combination)
@@ -84,7 +78,6 @@ public class PolarDataMiner {
private final CubicRegressionPerCourseProcessor cubicRegressionPerCourseProcessor;
private final SpeedRegressionPerAngleClusterProcessor speedRegressionPerAngleClusterProcessor;
private final ClusterGroup<Speed> speedClusterGroup;
private final ClusterGroup<Bearing> angleClusterGroup;
private ThreadPoolExecutor createExecutor() {
@@ -109,16 +102,15 @@ public class PolarDataMiner {
};
}
public PolarDataMiner(PolarSheetGenerationSettings backendPolarSettings, MovingAverageProcessor movingAverageProcessor,
CubicRegressionPerCourseProcessor cubicRegressionPerCourseProcessor, SpeedRegressionPerAngleClusterProcessor speedRegressionPerAngleClusterProcessor,
ClusterGroup<Speed> speedClusterGroup, ClusterGroup<Bearing> angleClusterGroup) {
public PolarDataMiner(PolarSheetGenerationSettings backendPolarSettings,
CubicRegressionPerCourseProcessor cubicRegressionPerCourseProcessor,
SpeedRegressionPerAngleClusterProcessor speedRegressionPerAngleClusterProcessor,
ClusterGroup<Bearing> angleClusterGroup) {
cubicRegressionPerCourseProcessor.setListeners(listeners);
speedRegressionPerAngleClusterProcessor.setListeners(listeners);
backendPolarSheetGenerationSettings = backendPolarSettings;
this.movingAverageProcessor = movingAverageProcessor;
this.cubicRegressionPerCourseProcessor = cubicRegressionPerCourseProcessor;
this.speedRegressionPerAngleClusterProcessor = speedRegressionPerAngleClusterProcessor;
this.speedClusterGroup = speedClusterGroup;
this.angleClusterGroup = angleClusterGroup;
try {
setUpWorkflow();
@@ -130,17 +122,6 @@ public class PolarDataMiner {
private void setUpWorkflow() throws ClassCastException, NoSuchMethodException,
SecurityException {
Collection<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>, ?>> movingAverageGrouperResultReceivers = new ArrayList<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>, ?>>();
movingAverageGrouperResultReceivers.add(movingAverageProcessor);
Collection<ParameterizedFunction<?>> parameterizedDimensions = new ArrayList<>();
for (Function<?> function : PolarDataDimensionCollectionFactory.getMovingAverageClusterKeyDimensions()) {
parameterizedDimensions.add(new SimpleParameterizedFunction<>(function, ParameterProvider.NULL));
}
Processor<GPSFixMovingWithPolarContext, GroupedDataEntry<GPSFixMovingWithPolarContext>> movingAverageGroupingProcessor = new ParallelMultiDimensionsValueNestingGroupingProcessor<GPSFixMovingWithPolarContext>(
GPSFixMovingWithPolarContext.class, executor, movingAverageGrouperResultReceivers, parameterizedDimensions);
Collection<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>, ?>> regressionPerCourseGrouperResultReceivers = new ArrayList<Processor<GroupedDataEntry<GPSFixMovingWithPolarContext>, ?>>();
regressionPerCourseGrouperResultReceivers.add(cubicRegressionPerCourseProcessor);
@@ -164,7 +145,6 @@ public class PolarDataMiner {
Collection<Processor<GPSFixMovingWithPolarContext, ?>> filteringResultReceivers = new ArrayList<>();
filteringResultReceivers.add(movingAverageGroupingProcessor);
filteringResultReceivers.add(cubicRegressionPerCourseGroupingProcessor);
filteringResultReceivers.add(regressionPerAngleClusterGroupingProcessor);
@@ -183,7 +163,7 @@ public class PolarDataMiner {
protected GPSFixMovingWithPolarContext enrich(GPSFixMovingWithOriginInfo element) {
GPSFixMovingWithPolarContext result = null;
result = new GPSFixMovingWithPolarContext(element.getFix(), element.getTrackedRace(),
element.getCompetitor(), speedClusterGroup, angleClusterGroup);
element.getCompetitor(), angleClusterGroup);
return result;
}
};
@@ -397,13 +377,9 @@ public class PolarDataMiner {
}
public SpeedWithBearingWithConfidence<Void> getAverageSpeedAndCourseOverGround(BoatClass boatClass,
Speed windSpeed, LegType legType, boolean useRegressionForSpeed) throws NotEnoughDataHasBeenAddedException {
Speed windSpeed, LegType legType) throws NotEnoughDataHasBeenAddedException {
SpeedWithBearingWithConfidence<Void> averageSpeedAndCourseOverGround = null;
if (useRegressionForSpeed) {
averageSpeedAndCourseOverGround = cubicRegressionPerCourseProcessor.getAverageSpeedAndCourseOverGround(boatClass, windSpeed, legType);
} else {
averageSpeedAndCourseOverGround = movingAverageProcessor.getAverageSpeedAndCourseOverGround(boatClass, windSpeed, legType);
}
averageSpeedAndCourseOverGround = cubicRegressionPerCourseProcessor.getAverageSpeedAndCourseOverGround(boatClass, windSpeed, legType);
return averageSpeedAndCourseOverGround;
}
@@ -453,10 +429,6 @@ public class PolarDataMiner {
}
}
public MovingAverageProcessor getMovingAverageProcessor() {
return movingAverageProcessor;
}
public CubicRegressionPerCourseProcessor getCubicRegressionPerCourseProcessor() {
return cubicRegressionPerCourseProcessor;
}
@@ -122,7 +122,7 @@ public class PolarResource extends AbstractSailingServerResource {
try {
PolarDataService service = getService().getPolarDataService();
SpeedWithBearingWithConfidence<Void> speedWithBearing = service.getAverageSpeedWithBearing(boatClass,
windSpeed, legType, tack, true);
windSpeed, legType, tack);
String resultString = "Speed: " + speedWithBearing.getObject().getKnots() + "kn; Angle: "
+ speedWithBearing.getObject().getBearing().getDegrees() + "°; Confidence: "
+ speedWithBearing.getConfidence();
@@ -57,9 +57,9 @@ public class PolarDiagramGPS extends PolarDiagramBase {
for (int i = 0; i < windSpeeds.size(); i++) {
try {
beatPort = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i), LegType.UPWIND,
Tack.PORT, true).getObject();
Tack.PORT).getObject();
beatStar = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i), LegType.UPWIND,
Tack.STARBOARD, true).getObject();
Tack.STARBOARD).getObject();
} catch (NotEnoughDataHasBeenAddedException e) {
beatPort = null;
beatStar = null;
@@ -86,9 +86,9 @@ public class PolarDiagramGPS extends PolarDiagramBase {
for (int i = 0; i < windSpeeds.size(); i++) {
try {
jibePort = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i),
LegType.DOWNWIND, Tack.PORT, true).getObject();
LegType.DOWNWIND, Tack.PORT).getObject();
jibeStar = this.polarData.getAverageSpeedWithBearing(this.boatClass, windSpeeds.get(i),
LegType.DOWNWIND, Tack.STARBOARD, true).getObject();
LegType.DOWNWIND, Tack.STARBOARD).getObject();
} catch (NotEnoughDataHasBeenAddedException e) {
jibePort = null;
jibeStar = null;
@@ -146,13 +146,13 @@ public class PolarDiagramGPSDirect implements PolarDiagram, Serializable {
try {
if (beatPort == null) {
SpeedWithBearing beatPortRelative = this.polarData.getAverageSpeedWithBearing(this.boatClass, wind,
LegType.UPWIND, Tack.PORT, true).getObject();
LegType.UPWIND, Tack.PORT).getObject();
beatPort = new KnotSpeedWithBearingImpl(beatPortRelative.getKnots(), this.wind.getBearing().reverse()
.add(beatPortRelative.getBearing()));
}
if (beatStar == null) {
SpeedWithBearing beatStarRelative = this.polarData.getAverageSpeedWithBearing(this.boatClass, wind,
LegType.UPWIND, Tack.STARBOARD, true).getObject();
LegType.UPWIND, Tack.STARBOARD).getObject();
beatStar = new KnotSpeedWithBearingImpl(beatStarRelative.getKnots(), this.wind.getBearing().reverse()
.add(beatStarRelative.getBearing()));
}
@@ -175,13 +175,13 @@ public class PolarDiagramGPSDirect implements PolarDiagram, Serializable {
try {
if (jibePort == null) {
SpeedWithBearing jibePortRelative = this.polarData.getAverageSpeedWithBearing(this.boatClass, wind,
LegType.DOWNWIND, Tack.PORT, true).getObject();
LegType.DOWNWIND, Tack.PORT).getObject();
jibePort = new KnotSpeedWithBearingImpl(jibePortRelative.getKnots(), this.wind.getBearing().reverse()
.add(jibePortRelative.getBearing()));
}
if (jibeStar == null) {
SpeedWithBearing jibeStarRelative = this.polarData.getAverageSpeedWithBearing(this.boatClass, wind,
LegType.DOWNWIND, Tack.STARBOARD, true).getObject();
LegType.DOWNWIND, Tack.STARBOARD).getObject();
jibeStar = new KnotSpeedWithBearingImpl(jibeStarRelative.getKnots(), this.wind.getBearing().reverse()
.add(jibeStarRelative.getBearing()));
}