bug6092: refactored tracked leg of competitor retrieval chains for terminal and ongoing

This commit is contained in:
Axel Uhl
2025-02-12 22:27:44 +01:00
parent c86ac61794
commit d727182719
11 changed files with 257 additions and 168 deletions
@@ -24,6 +24,7 @@ import com.sap.sailing.datamining.data.HasTrackedLegSliceOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTrackedRaceContext;
import com.sap.sailing.datamining.data.HasWindFixContext;
import com.sap.sailing.datamining.data.HasWindTrackContext;
import com.sap.sailing.datamining.data.TerminalHasTrackedLegSliceOfCompetitorContext;
import com.sap.sailing.datamining.impl.components.BravoFixRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.BravoFixTrackRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.CompetitorDayRetrievalProcessor;
@@ -39,6 +40,7 @@ import com.sap.sailing.datamining.impl.components.ManeuverSpeedDetailsRetrievalP
import com.sap.sailing.datamining.impl.components.MarkPassingRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.RaceOfCompetitorRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TackTypeSegmentRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TerminalTrackedLegOfCompetitorRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedLegOfCompetitorRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedLegRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedLegSliceOfCompetitorRetrievalProcessor;
@@ -130,7 +132,13 @@ public class SailingDataRetrievalChainDefinitions {
// use TackTypeSegmentsDataMiningSettings here to support the per-leg statistics about tack type segments
legOfCompetitorRetrieverChainDefinition.endWith(TrackedLegRetrievalProcessor.class, TrackedLegOfCompetitorRetrievalProcessor.class,
HasTrackedLegOfCompetitorContext.class, TackTypeSegmentsDataMiningSettings.class, TackTypeSegmentsDataMiningSettings.createDefaultSettings(), "LegOfCompetitor");
dataRetrieverChainDefinitions.add(legOfCompetitorRetrieverChainDefinition);
//
final DataRetrieverChainDefinition<RacingEventService, TerminalHasTrackedLegSliceOfCompetitorContext> terminalLegOfCompetitorRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
legRetrieverChainDefinition, TerminalHasTrackedLegSliceOfCompetitorContext.class, "LegOfCompetitorSailingDomainRetrieverChain");
// use TackTypeSegmentsDataMiningSettings here to support the per-leg statistics about tack type segments
terminalLegOfCompetitorRetrieverChainDefinition.endWith(TrackedLegRetrievalProcessor.class, TerminalTrackedLegOfCompetitorRetrievalProcessor.class,
TerminalHasTrackedLegSliceOfCompetitorContext.class, TackTypeSegmentsDataMiningSettings.class, TackTypeSegmentsDataMiningSettings.createDefaultSettings(), "LegOfCompetitor");
dataRetrieverChainDefinitions.add(terminalLegOfCompetitorRetrieverChainDefinition);
// tenth of a competitor's tracked leg retriever, based on the tracked leg of competitor retriever:
final DataRetrieverChainDefinition<RacingEventService, HasTrackedLegSliceOfCompetitorContext> legOfCompetitorSliceRetrieverChainDefinition = new SimpleDataRetrieverChainDefinition<>(
legOfCompetitorRetrieverChainDefinition, HasTrackedLegSliceOfCompetitorContext.class, "LegOfCompetitorSliceSailingDomainRetrieverChain");
@@ -15,7 +15,7 @@ import com.sap.sailing.datamining.impl.components.GPSFixRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.LeaderboardGroupRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.LeaderboardRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.RaceOfCompetitorRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedLegOfCompetitorRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TerminalTrackedLegOfCompetitorRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedLegRetrievalProcessor;
import com.sap.sailing.datamining.impl.components.TrackedRaceRetrievalProcessor;
import com.sap.sailing.domain.common.LegType;
@@ -66,7 +66,7 @@ public class SailingPredefinedQueries {
retrieverLevels.add(new DataRetrieverLevelDTO(1, LeaderboardRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasLeaderboardContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(2, TrackedRaceRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedRaceContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(3, TrackedLegRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(4, TrackedLegOfCompetitorRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegOfCompetitorContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(4, TerminalTrackedLegOfCompetitorRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegOfCompetitorContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(5, GPSFixRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasGPSFixContext.class.getName(), ""), null));
DataRetrieverChainDefinitionDTO retrieverChain = new DataRetrieverChainDefinitionDTO("", RacingEventService.class.getName(), retrieverLevels);
@@ -90,7 +90,7 @@ public class SailingPredefinedQueries {
retrieverLevels.add(new DataRetrieverLevelDTO(1, LeaderboardRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasLeaderboardContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(2, TrackedRaceRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedRaceContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(3, TrackedLegRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(4, TrackedLegOfCompetitorRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegOfCompetitorContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(4, TerminalTrackedLegOfCompetitorRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegOfCompetitorContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(5, GPSFixRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasGPSFixContext.class.getName(), ""), null));
DataRetrieverChainDefinitionDTO retrieverChain = new DataRetrieverChainDefinitionDTO("", RacingEventService.class.getName(), retrieverLevels);
@@ -114,7 +114,7 @@ public class SailingPredefinedQueries {
retrieverLevels.add(new DataRetrieverLevelDTO(1, LeaderboardRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasLeaderboardContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(2, TrackedRaceRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedRaceContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(3, TrackedLegRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(4, TrackedLegOfCompetitorRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegOfCompetitorContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(4, TerminalTrackedLegOfCompetitorRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegOfCompetitorContext.class.getName(), ""), null));
DataRetrieverChainDefinitionDTO retrieverChain = new DataRetrieverChainDefinitionDTO("", RacingEventService.class.getName(), retrieverLevels);
ModifiableStatisticQueryDefinitionDTO queryDefinition = new ModifiableStatisticQueryDefinitionDTO("default", statistic, aggregator, retrieverChain);
@@ -137,7 +137,7 @@ public class SailingPredefinedQueries {
retrieverLevels.add(new DataRetrieverLevelDTO(1, LeaderboardRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasLeaderboardContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(2, TrackedRaceRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedRaceContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(3, TrackedLegRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(4, TrackedLegOfCompetitorRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegOfCompetitorContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(4, TerminalTrackedLegOfCompetitorRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegOfCompetitorContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(5, GPSFixRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasGPSFixContext.class.getName(), ""), null));
DataRetrieverChainDefinitionDTO retrieverChain = new DataRetrieverChainDefinitionDTO("", RacingEventService.class.getName(), retrieverLevels);
@@ -158,7 +158,7 @@ public class SailingPredefinedQueries {
retrieverLevels.add(new DataRetrieverLevelDTO(1, LeaderboardRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasLeaderboardContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(2, TrackedRaceRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedRaceContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(3, TrackedLegRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(4, TrackedLegOfCompetitorRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegOfCompetitorContext.class.getName(), ""), null));
retrieverLevels.add(new DataRetrieverLevelDTO(4, TerminalTrackedLegOfCompetitorRetrievalProcessor.class.getName(), new LocalizedTypeDTO(HasTrackedLegOfCompetitorContext.class.getName(), ""), null));
DataRetrieverChainDefinitionDTO retrieverChain = new DataRetrieverChainDefinitionDTO("", RacingEventService.class.getName(), retrieverLevels);
ModifiableStatisticQueryDefinitionDTO queryDefinition = new ModifiableStatisticQueryDefinitionDTO("default", statistic, aggregator, retrieverChain);
@@ -1,131 +0,0 @@
package com.sap.sailing.datamining.data;
import com.sap.sailing.domain.base.Boat;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.Distance;
import com.sap.sse.common.Duration;
import com.sap.sse.common.Speed;
import com.sap.sse.datamining.annotations.Connector;
import com.sap.sse.datamining.annotations.Dimension;
import com.sap.sse.datamining.annotations.Statistic;
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
/**
* A "slice" of a competitor's tracked leg; slicing may happen in the retriever, perhaps influenced by some
* configuration parameters, e.g., based on windward distance sailed, time spent, or rhumb line distance sailed.
* A full leg is a special case of this.
*
* @author Axel Uhl (d043530)
*
*/
public interface AbstractHasTrackedLegSliceOfCompetitorContext extends HasSomethingOfCompetitorContextWithTrackedRaceContext {
@Connector(scanForStatistics=false)
HasTrackedLegContext getTrackedLegContext();
default TrackedRace getTrackedRace() {
return getTrackedLegContext().getTrackedRaceContext().getTrackedRace();
}
TrackedLegOfCompetitor getTrackedLegOfCompetitor();
default HasTrackedRaceContext getTrackedRaceContext() {
return getTrackedLegContext().getTrackedRaceContext();
}
@Dimension(messageKey="RelativeScoreInRaceInPercent", ordinal=12)
ClusterDTO getPercentageClusterForRelativeScoreInRace();
@Connector(messageKey="Boat")
Boat getBoat();
@Statistic(messageKey="DistanceTraveled", resultDecimals=2, ordinal=0)
Distance getDistanceTraveled();
@Statistic(messageKey="SpeedAverage", resultDecimals=2, ordinal=0)
Double getSpeedAverageInKnots();
@Statistic(messageKey="RankGainsOrLosses", resultDecimals=2, ordinal=1)
Integer getRankGainsOrLosses();
@Statistic(messageKey="RelativeScore", resultDecimals=2, ordinal=2)
Double getRelativeRank();
@Statistic(messageKey="AbsoluteRank", resultDecimals=0, ordinal=3)
Integer getRankAtSliceFinish();
@Statistic(messageKey="AbsoluteRankAfterFirstQuarter", resultDecimals=0, ordinal=4)
Integer getRankAfterFirstQuarter();
@Statistic(messageKey="AbsoluteRankAfterSecondQuarter", resultDecimals=0, ordinal=5)
Integer getRankAfterSecondQuarter();
@Statistic(messageKey="AbsoluteRankAfterThirdQuarter", resultDecimals=0, ordinal=6)
Integer getRankAfterThirdQuarter();
@Statistic(messageKey="AbsoluteRankAverageAcrossFirstThreeQuarters", resultDecimals=2, ordinal=7)
Double getRankAverageAcrossFirstThreeQuarters();
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAfterFirstQuarter", resultDecimals=0, ordinal=8)
Integer getRankRhumbLineBasedAfterFirstQuarter();
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAfterSecondQuarter", resultDecimals=0, ordinal=9)
Integer getRankRhumbLineBasedAfterSecondQuarter();
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAfterThirdQuarter", resultDecimals=0, ordinal=10)
Integer getRankRhumbLineBasedAfterThirdQuarter();
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAverageAcrossFirstThreeQuarters", resultDecimals=2, ordinal=11)
Double getRankRhumbLineBasedAverageAcrossFirstThreeQuarters();
@Statistic(messageKey="AbsoluteRankPredictionErrorAfterFirstQuarter", resultDecimals=2, ordinal=12)
Double getRankPredictionErrorAfterFirstQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorAfterSecondQuarter", resultDecimals=2, ordinal=13)
Double getRankPredictionErrorAfterSecondQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorAfterThirdQuarter", resultDecimals=2, ordinal=14)
Double getRankPredictionErrorAfterThirdQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorAcrossFirstThreeQuarters", resultDecimals=2, ordinal=15)
Double getRankPredictionErrorAcrossFirstThreeQuarters();
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAfterFirstQuarter", resultDecimals=2, ordinal=16)
Double getRankPredictionErrorRhumbLineBasedAfterFirstQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAfterSecondQuarter", resultDecimals=2, ordinal=17)
Double getRankPredictionErrorRhumbLineBasedAfterSecondQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAfterThirdQuarter", resultDecimals=2, ordinal=18)
Double getRankPredictionErrorRhumbLineBasedAfterThirdQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAcrossFirstThreeQuarters", resultDecimals=2, ordinal=19)
Double getRankPredictionErrorRhumbLineBasedAcrossFirstThreeQuarters();
@Statistic(messageKey="TimeSpentInSeconds", resultDecimals=0, ordinal=4)
Long getTimeTakenInSeconds();
@Statistic(messageKey="timeSpentFoiling", resultDecimals=1)
Duration getTimeSpentFoiling();
@Statistic(messageKey="FoilingDistance", resultDecimals=1)
Distance getDistanceSpentFoiling();
@Statistic(messageKey="NumberOfManeuvers", resultDecimals=0)
Integer getNumberOfManeuvers();
@Statistic(messageKey="NumberOfJibes", resultDecimals=0)
Integer getNumberOfJibes();
@Statistic(messageKey="NumberOfTacks", resultDecimals=0)
Integer getNumberOfTacks();
@Statistic(messageKey="VMG", resultDecimals=2)
Speed getVelocityMadeGood();
@Statistic(messageKey="RatioDurationLongVsShortTack", resultDecimals=2)
double getRatioDurationLongVsShortTack();
@Statistic(messageKey="RatioDistanceLongVsShortTack", resultDecimals=2)
double getRatioDistanceLongVsShortTack();
}
@@ -1,5 +1,5 @@
package com.sap.sailing.datamining.data;
public interface HasTrackedLegOfCompetitor {
AbstractHasTrackedLegSliceOfCompetitorContext getTrackedLegOfCompetitorContext();
HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext();
}
@@ -1,4 +1,131 @@
package com.sap.sailing.datamining.data;
public interface HasTrackedLegOfCompetitorContext extends AbstractHasTrackedLegSliceOfCompetitorContext {
import com.sap.sailing.domain.base.Boat;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.Distance;
import com.sap.sse.common.Duration;
import com.sap.sse.common.Speed;
import com.sap.sse.datamining.annotations.Connector;
import com.sap.sse.datamining.annotations.Dimension;
import com.sap.sse.datamining.annotations.Statistic;
import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
/**
* A "slice" of a competitor's tracked leg; slicing may happen in the retriever, perhaps influenced by some
* configuration parameters, e.g., based on windward distance sailed, time spent, or rhumb line distance sailed.
* A full leg is a special case of this.
*
* @author Axel Uhl (d043530)
*
*/
public interface HasTrackedLegOfCompetitorContext extends HasSomethingOfCompetitorContextWithTrackedRaceContext {
@Connector(scanForStatistics=false)
HasTrackedLegContext getTrackedLegContext();
default TrackedRace getTrackedRace() {
return getTrackedLegContext().getTrackedRaceContext().getTrackedRace();
}
TrackedLegOfCompetitor getTrackedLegOfCompetitor();
default HasTrackedRaceContext getTrackedRaceContext() {
return getTrackedLegContext().getTrackedRaceContext();
}
@Dimension(messageKey="RelativeScoreInRaceInPercent", ordinal=12)
ClusterDTO getPercentageClusterForRelativeScoreInRace();
@Connector(messageKey="Boat")
Boat getBoat();
@Statistic(messageKey="DistanceTraveled", resultDecimals=2, ordinal=0)
Distance getDistanceTraveled();
@Statistic(messageKey="SpeedAverage", resultDecimals=2, ordinal=0)
Double getSpeedAverageInKnots();
@Statistic(messageKey="RankGainsOrLosses", resultDecimals=2, ordinal=1)
Integer getRankGainsOrLosses();
@Statistic(messageKey="RelativeScore", resultDecimals=2, ordinal=2)
Double getRelativeRank();
@Statistic(messageKey="AbsoluteRank", resultDecimals=0, ordinal=3)
Integer getRankAtSliceFinish();
@Statistic(messageKey="AbsoluteRankAfterFirstQuarter", resultDecimals=0, ordinal=4)
Integer getRankAfterFirstQuarter();
@Statistic(messageKey="AbsoluteRankAfterSecondQuarter", resultDecimals=0, ordinal=5)
Integer getRankAfterSecondQuarter();
@Statistic(messageKey="AbsoluteRankAfterThirdQuarter", resultDecimals=0, ordinal=6)
Integer getRankAfterThirdQuarter();
@Statistic(messageKey="AbsoluteRankAverageAcrossFirstThreeQuarters", resultDecimals=2, ordinal=7)
Double getRankAverageAcrossFirstThreeQuarters();
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAfterFirstQuarter", resultDecimals=0, ordinal=8)
Integer getRankRhumbLineBasedAfterFirstQuarter();
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAfterSecondQuarter", resultDecimals=0, ordinal=9)
Integer getRankRhumbLineBasedAfterSecondQuarter();
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAfterThirdQuarter", resultDecimals=0, ordinal=10)
Integer getRankRhumbLineBasedAfterThirdQuarter();
@Statistic(messageKey="AbsoluteRankRhumbLineBasedAverageAcrossFirstThreeQuarters", resultDecimals=2, ordinal=11)
Double getRankRhumbLineBasedAverageAcrossFirstThreeQuarters();
@Statistic(messageKey="AbsoluteRankPredictionErrorAfterFirstQuarter", resultDecimals=2, ordinal=12)
Double getRankPredictionErrorAfterFirstQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorAfterSecondQuarter", resultDecimals=2, ordinal=13)
Double getRankPredictionErrorAfterSecondQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorAfterThirdQuarter", resultDecimals=2, ordinal=14)
Double getRankPredictionErrorAfterThirdQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorAcrossFirstThreeQuarters", resultDecimals=2, ordinal=15)
Double getRankPredictionErrorAcrossFirstThreeQuarters();
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAfterFirstQuarter", resultDecimals=2, ordinal=16)
Double getRankPredictionErrorRhumbLineBasedAfterFirstQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAfterSecondQuarter", resultDecimals=2, ordinal=17)
Double getRankPredictionErrorRhumbLineBasedAfterSecondQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAfterThirdQuarter", resultDecimals=2, ordinal=18)
Double getRankPredictionErrorRhumbLineBasedAfterThirdQuarter();
@Statistic(messageKey="AbsoluteRankPredictionErrorRhumbLineBasedAcrossFirstThreeQuarters", resultDecimals=2, ordinal=19)
Double getRankPredictionErrorRhumbLineBasedAcrossFirstThreeQuarters();
@Statistic(messageKey="TimeSpentInSeconds", resultDecimals=0, ordinal=4)
Long getTimeTakenInSeconds();
@Statistic(messageKey="timeSpentFoiling", resultDecimals=1)
Duration getTimeSpentFoiling();
@Statistic(messageKey="FoilingDistance", resultDecimals=1)
Distance getDistanceSpentFoiling();
@Statistic(messageKey="NumberOfManeuvers", resultDecimals=0)
Integer getNumberOfManeuvers();
@Statistic(messageKey="NumberOfJibes", resultDecimals=0)
Integer getNumberOfJibes();
@Statistic(messageKey="NumberOfTacks", resultDecimals=0)
Integer getNumberOfTacks();
@Statistic(messageKey="VMG", resultDecimals=2)
Speed getVelocityMadeGood();
@Statistic(messageKey="RatioDurationLongVsShortTack", resultDecimals=2)
double getRatioDurationLongVsShortTack();
@Statistic(messageKey="RatioDistanceLongVsShortTack", resultDecimals=2)
double getRatioDistanceLongVsShortTack();
}
@@ -12,9 +12,14 @@ import com.sap.sailing.domain.tracking.TrackedRace;
*
*/
public interface TerminalHasTrackedLegSliceOfCompetitorContext
extends AbstractHasTrackedLegSliceOfCompetitorContext, HasWindOnTrackedLegOfCompetitor {
extends HasTrackedLegOfCompetitorContext, HasWindOnTrackedLegOfCompetitor {
@Override
default TrackedRace getTrackedRace() {
return AbstractHasTrackedLegSliceOfCompetitorContext.super.getTrackedRace();
return HasTrackedLegOfCompetitorContext.super.getTrackedRace();
}
@Override
default HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext() {
return this;
}
}
@@ -0,0 +1,51 @@
package com.sap.sailing.datamining.impl.components;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.TerminalHasTrackedLegSliceOfCompetitorContext;
import com.sap.sailing.datamining.impl.data.TerminalTrackedLegOfCompetitorWithContext;
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
import com.sap.sailing.domain.base.Competitor;
import com.sap.sse.datamining.components.Processor;
import com.sap.sse.datamining.impl.components.AbstractRetrievalProcessor;
import com.sap.sse.security.shared.impl.SecuredSecurityTypes;
public class TerminalTrackedLegOfCompetitorRetrievalProcessor extends AbstractRetrievalProcessor<HasTrackedLegContext, TerminalHasTrackedLegSliceOfCompetitorContext> {
/**
* Settings will be used to control the retrieval of tack type segments for the
* corresponding statistics such as distance/duration relation between long and
* short tack for the leg of the competitor
*/
private final TackTypeSegmentsDataMiningSettings settings;
public TerminalTrackedLegOfCompetitorRetrievalProcessor(ExecutorService executor,
Collection<Processor<TerminalHasTrackedLegSliceOfCompetitorContext, ?>> resultReceivers,
TackTypeSegmentsDataMiningSettings settings, int retrievalLevel, String retrievedDataTypeMessageKey) {
super(HasTrackedLegContext.class, TerminalHasTrackedLegSliceOfCompetitorContext.class, executor, resultReceivers,
retrievalLevel, retrievedDataTypeMessageKey);
this.settings = settings;
}
@Override
protected Iterable<TerminalHasTrackedLegSliceOfCompetitorContext> retrieveData(HasTrackedLegContext element) {
final Collection<TerminalHasTrackedLegSliceOfCompetitorContext> trackedLegOfCompetitorsWithContext = new ArrayList<>();
for (Competitor competitor : element.getTrackedRaceContext().getTrackedRace().getRace().getCompetitors()) {
if (isAborted()) {
break;
}
final Subject subject = SecurityUtils.getSubject();
if (subject.isPermitted(competitor.getIdentifier().getStringPermission(SecuredSecurityTypes.PublicReadableActions.READ_PUBLIC))) {
TerminalHasTrackedLegSliceOfCompetitorContext trackedLegOfCompetitorWithContext = new TerminalTrackedLegOfCompetitorWithContext(element, element.getTrackedLeg().getTrackedLeg(competitor), settings);
trackedLegOfCompetitorsWithContext.add(trackedLegOfCompetitorWithContext);
}
}
return trackedLegOfCompetitorsWithContext;
}
}
@@ -10,7 +10,7 @@ import java.util.function.Supplier;
import com.sap.sailing.datamining.Activator;
import com.sap.sailing.datamining.SailingClusterGroups;
import com.sap.sailing.datamining.data.AbstractHasTrackedLegSliceOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTackTypeSegmentContext;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.impl.components.TackTypeSegmentRetrievalProcessor;
@@ -20,6 +20,8 @@ import com.sap.sailing.domain.base.Competitor;
import com.sap.sailing.domain.common.LegType;
import com.sap.sailing.domain.common.ManeuverType;
import com.sap.sailing.domain.common.NoWindException;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.Positioned;
import com.sap.sailing.domain.leaderboard.Leaderboard;
import com.sap.sailing.domain.leaderboard.caching.LeaderboardDTOCalculationReuseCache;
import com.sap.sailing.domain.tracking.BravoFixTrack;
@@ -43,7 +45,8 @@ import com.sap.sse.datamining.shared.impl.dto.ClusterDTO;
* harder to implement because we would need to find out iteratively, between which fixes the competitor sailed, say, one tenth of the
* windward distance in the leg.
*/
public abstract class AbstractTrackedLegSliceOfCompetitorWithContext implements AbstractHasTrackedLegSliceOfCompetitorContext {
public abstract class AbstractTrackedLegSliceOfCompetitorWithContext implements HasTrackedLegOfCompetitorContext, Positioned {
private static final long serialVersionUID = 7748860191111327007L;
private static final long DEFAULT_NUMBER_OF_SLICES = 10;
private final HasTrackedLegContext trackedLegContext;
@@ -588,6 +591,21 @@ public abstract class AbstractTrackedLegSliceOfCompetitorWithContext implements
.filter(tt->tt.getLegNumber() == getTrackedLegContext().getLegNumber()).collect(resultProcessor);
}
@Override
public Position getPosition() {
final TrackedLeg trackedLeg = getTrackedLegContext().getTrackedLeg();
final TrackedRace trackedRace = trackedLeg.getTrackedRace();
final TimePoint timepoint = getTimePointBetweenLegSliceStartAndLegFinish(trackedRace);
final Position result;
if (timepoint == null) {
result = null;
} else {
result = trackedLeg.getMiddleOfLeg(timepoint);
}
return result;
}
protected Integer getTheSliceNumber() {
return sliceNumber;
}
@@ -1,15 +1,11 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.AbstractHasTrackedLegSliceOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.TerminalHasTrackedLegSliceOfCompetitorContext;
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
import com.sap.sailing.domain.common.Position;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.tracking.TrackedLeg;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sailing.domain.tracking.TrackedRace;
import com.sap.sse.common.TimePoint;
/**
* Abstract base class of those tracked legs of competitor in Data Mining that are returned as terminal
@@ -22,7 +18,6 @@ import com.sap.sse.common.TimePoint;
*/
public abstract class TerminalAbstractTrackedLegSliceOfCompetitorWithContext extends
AbstractTrackedLegSliceOfCompetitorWithContext implements TerminalHasTrackedLegSliceOfCompetitorContext {
private static final long serialVersionUID = 8362729373776291159L;
private Wind wind;
@@ -31,7 +26,7 @@ public abstract class TerminalAbstractTrackedLegSliceOfCompetitorWithContext ext
}
@Override
public AbstractHasTrackedLegSliceOfCompetitorContext getTrackedLegOfCompetitorContext() {
public HasTrackedLegOfCompetitorContext getTrackedLegOfCompetitorContext() {
return this;
}
@@ -44,20 +39,4 @@ public abstract class TerminalAbstractTrackedLegSliceOfCompetitorWithContext ext
public void setWindInternal(Wind wind) {
this.wind = wind;
}
@Override
public Position getPosition() {
final TrackedLeg trackedLeg = getTrackedLegContext().getTrackedLeg();
final TrackedRace trackedRace = trackedLeg.getTrackedRace();
final TimePoint timepoint = getTimePointBetweenLegSliceStartAndLegFinish(trackedRace);
final Position result;
if (timepoint == null) {
result = null;
} else {
result = trackedLeg.getMiddleOfLeg(timepoint);
}
return result;
}
}
@@ -0,0 +1,30 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.TerminalHasTrackedLegSliceOfCompetitorContext;
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
import com.sap.sailing.domain.common.Wind;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
/**
* Equality is based on the {@link #getTrackedLegOfCompetitor()} only. The {@link #getSliceNumber()} defaults to {@code 1} for this
* special case of the entire leg. Start and finish times of this "slice" equal the start/finish times of the competitor in the leg.
*/
public class TerminalTrackedLegOfCompetitorWithContext extends TrackedLegOfCompetitorWithContext implements TerminalHasTrackedLegSliceOfCompetitorContext {
private static final long serialVersionUID = 6464926225236850592L;
private Wind wind;
public TerminalTrackedLegOfCompetitorWithContext(HasTrackedLegContext trackedLegContext, TrackedLegOfCompetitor trackedLegOfCompetitor, TackTypeSegmentsDataMiningSettings settings) {
super(trackedLegContext, trackedLegOfCompetitor, settings);
}
@Override
public Wind getWindInternal() {
return wind;
}
@Override
public void setWindInternal(Wind wind) {
this.wind = wind;
}
}
@@ -1,8 +1,8 @@
package com.sap.sailing.datamining.impl.data;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.data.HasTackTypeSegmentContext;
import com.sap.sailing.datamining.data.HasTrackedLegContext;
import com.sap.sailing.datamining.data.HasTrackedLegOfCompetitorContext;
import com.sap.sailing.datamining.shared.TackTypeSegmentsDataMiningSettings;
import com.sap.sailing.domain.tracking.TrackedLegOfCompetitor;
import com.sap.sse.common.Distance;
@@ -14,6 +14,8 @@ import com.sap.sse.common.TimePoint;
* special case of the entire leg. Start and finish times of this "slice" equal the start/finish times of the competitor in the leg.
*/
public class TrackedLegOfCompetitorWithContext extends AbstractTrackedLegSliceOfCompetitorWithContext implements HasTrackedLegOfCompetitorContext {
private static final long serialVersionUID = 3966524650275310718L;
public TrackedLegOfCompetitorWithContext(HasTrackedLegContext trackedLegContext, TrackedLegOfCompetitor trackedLegOfCompetitor, TackTypeSegmentsDataMiningSettings settings) {
super(trackedLegContext, trackedLegOfCompetitor, settings, 1);
}