diff --git a/MAT.SQLRace.BaseExampleLoadSSN/Program.cs b/MAT.SQLRace.BaseExampleLoadSSN/Program.cs
index 637ae71..277a6ac 100644
--- a/MAT.SQLRace.BaseExampleLoadSSN/Program.cs
+++ b/MAT.SQLRace.BaseExampleLoadSSN/Program.cs
@@ -69,7 +69,7 @@ private static void ReadSamples(IClientSession clientSession)
private static IClientSession LoadSession(string pathToFile)
{
var fileSessionManager = FileSessionManager.CreateFileSessionManager();
- var clientSession = fileSessionManager.Load(pathToFile); // session with associates
+ var clientSession = fileSessionManager.Load(pathToFile);
if (clientSession == null)
{
diff --git a/MAT.SQLRace.HelloData/FunctionHelper.cs b/MAT.SQLRace.HelloData/FunctionHelper.cs
index 8693acc..ba06936 100644
--- a/MAT.SQLRace.HelloData/FunctionHelper.cs
+++ b/MAT.SQLRace.HelloData/FunctionHelper.cs
@@ -2,6 +2,7 @@
// Copyright (c) Motion Applied Ltd.
using System;
+using System.Text;
using MESL.SqlRace.Domain.Functions;
using MESL.SqlRace.Domain.Functions.Fdl;
@@ -51,5 +52,70 @@ public static IFunctionDefinition CreateFdlFunctionDefinition(IFunctionManager f
return functionDefinition;
}
+
+ public static IFunctionDefinition CreateFdlFunctionDefinition(
+ IFunctionManager functionManager,
+ string[] parameterIdentifiers,
+ FunctionMode functionMode = FunctionMode.Instantaneous)
+ {
+ if (parameterIdentifiers == null ||
+ parameterIdentifiers.Length == 0)
+ {
+ throw new InvalidOperationException("Parameters expected not to be empty.");
+ }
+
+ const string FunctionName = "ParametersCombined";
+
+ //Create function
+ var parameterCode = new StringBuilder();
+ for (var i = 0; i < parameterIdentifiers.Length; i++)
+ {
+ var parameterIdentifier = parameterIdentifiers[i];
+
+ parameterCode.Append("$");
+ parameterCode.Append(parameterIdentifier);
+
+ if (i < parameterIdentifiers.Length - 1)
+ {
+ parameterCode.Append(" + ");
+ }
+ }
+
+ var parametersDoubled = $"return ({parameterCode})";
+
+ var functionDefinition = functionManager.CreateFunctionDefinition(FdlFunctionConstants.UniqueId);
+
+ // The implementation of a function is completely agnostic. We requested a function definition from
+ // the FDL runtime, so the generic function implementation definition in the definition returned can
+ // be safely cast to the more specific FDL implementation definition.
+ var fdlFunctionImplementationDefinition = (IFdlFunctionImplementationDefinition)functionDefinition.ImplementationDefinition;
+ fdlFunctionImplementationDefinition.FunctionCode = parametersDoubled;
+
+ // FDL doesn't define the output for a single parameter - it's simply the return value of the
+ // function - so we have to tell the function executor what to do with the output it generates
+ var outputParameter = FunctionOutputParameterDefinition
+ .Create($"{FunctionName}", "FunctionParameters", "Parameters Combined")
+ .Units("kph")
+ .FormatOverride("%.2f")
+ .MinimumValue("0.0")
+ .MaximumValue("700.0");
+
+ functionDefinition.OutputParameterDefinitions.Add(outputParameter);
+
+ // Functions in ATLAS 9 have a number of different properties that define how, where, when and on
+ // what a function executes. ATLAS 10 will add more of these properties. Each value here is the
+ // default for its property, shown for illustration.
+ functionDefinition.Name = $"{FunctionName}";
+ functionDefinition.FunctionMode = functionMode;
+ functionDefinition.CalculationModeInfoDefinition.Mode = CalculationMode.EachSamplePoint;
+ functionDefinition.InterpolateBetweenSamples = false;
+ functionDefinition.JoinGapsAroundNull = true;
+ functionDefinition.CalculateOverWholeSession = false;
+ functionDefinition.StoreInSession = false;
+ functionDefinition.ShouldHide = false;
+ functionDefinition.ShouldPersist = false;
+
+ return functionDefinition;
+ }
}
}
\ No newline at end of file
diff --git a/MAT.SQLRace.HelloData/Program.cs b/MAT.SQLRace.HelloData/Program.cs
index 9e4c92e..a585df8 100644
--- a/MAT.SQLRace.HelloData/Program.cs
+++ b/MAT.SQLRace.HelloData/Program.cs
@@ -2,15 +2,19 @@
// Copyright (c) Motion Applied Ltd.
using MAT.OCS.Core;
+
using MESL.SqlRace.Common.Extensions;
using MESL.SqlRace.Domain;
using MESL.SqlRace.Domain.Collections;
+using MESL.SqlRace.Domain.Events;
using MESL.SqlRace.Domain.Functions;
+using MESL.SqlRace.Domain.Infrastructure.DataPipeline;
using MESL.SqlRace.Domain.Infrastructure.Enumerators;
using MESL.SqlRace.Domain.Query;
using MESL.SqlRace.Enumerators;
+using MESL.SqlRace.Functions.Interfaces.Enums;
using MESL.SqlRace.UI;
-using MESL.SqlRace.Domain.Events;
+
using System;
using System.Collections.Generic;
using System.Diagnostics;
@@ -18,9 +22,6 @@
using System.Threading;
using System.Threading.Tasks;
-using MESL.SqlRace.Domain.Infrastructure.DataPipeline;
-using MESL.SqlRace.Functions.Interfaces.Enums;
-
namespace MAT.SQLRace.HelloData
{
internal class Program
@@ -57,24 +58,27 @@ private static void Main(string[] args)
//LapStatistics();
//ConnectionManagerTest();
//CreateSessionAndAddData();
- //CompositeSessionTestWithAppendedSessions();
+ //AppendSessions();
//CompositeSessionWithvTagSessionsTest();
//AddInMemoryParameterToSession();
//AddParameterToExistingSession();
//ChannelStats();
//Benchmark();
- //LoadAssociated();
+ //GetAssociatedSessionSummaries();
- //LoadSSNWithAssociatedMerge();
//AddEvents();
//LoadLiveSessionAndWaitForLapEvents();
//LoadLiveSessionAndWaitForEvents();
//LoadLiveSamples();
//AddAndProcessMarkers();
LoadSSN();
+ //LoadSSNWtihAssociates();
+ //LoadSqlRaceDatabaseSessionWithAssociates();
+ //LoadSessionViaQueryManagerWithAssociate();
//GetSessionSummaryBySessionGUID();
//LoadLiveFunction();
+ //CreateFunctionAcrossMultipleSessionsWithCompositeSession();
//WholeSessionsCompareMode();
//TestMaxAndMinSampleIntervals();
@@ -283,28 +287,31 @@ private static long[] CreateTimestampsForTimerange(long startTime, long endTime,
}
///
- /// Loads a session with an associated session
+ /// This example demonstrates how to get associated session summaries for a given session
+ /// from a SQL backed session database. It retrieves the list of associated sessions
+ /// and prints their identifiers.
+ ///
+ /// This is particularly useful in situations where you know you want to load associate
+ /// sessions but do not yet know which associates are available. The returned summaries
+ /// can be inspected to decide which associates to load or process next.
///
- private static void LoadAssociated()
+ private static void GetAssociatedSessionSummaries()
{
- ConnectionString = @"Data Source=mesltgs1;Initial Catalog=SQLRACE143;Integrated Security=True";
+ // ========= EDITABLE SECTION (tweak these values for your run) =========
+ const string connectionString = @"";
+ const string sessionKeyValue = "";
+ // =====================================================================
- string parameterIdentifier = "BAeroAutoZero:MRLAero";
- SessionKey sessionKey = new SessionKey("3FA70D1D-F526-4A10-9396-589B3BE23625");
+ ConnectionString = connectionString;
- var sessionManager = SessionManager.CreateSessionManager();
- var sessionSummaries = sessionManager.LoadAssociatesForSession(sessionKey, ConnectionString);
- var additionalSessionKey = sessionSummaries.OrderBy(ss => ss.TimeOfRecording).Last();
- IClientSession clientSession = sessionManager.Load(sessionKey, ConnectionString, new[] { additionalSessionKey.Key });
+ var sessionKey = new SessionKey(sessionKeyValue);
- var containsChannel = clientSession.Session.ContainsParameter(parameterIdentifier);
- Console.WriteLine(
- $"Parameter {parameterIdentifier} exists in session: {containsChannel}");
+ var sessionManager = SessionManager.CreateSessionManager();
- using (var pda = clientSession.Session.CreateParameterDataAccess(parameterIdentifier))
+ var sessionSummaries = sessionManager.LoadAssociatesForSession(sessionKey, ConnectionString);
+ foreach (var sessionSummary in sessionSummaries)
{
- Console.WriteLine(
- $"PDA {parameterIdentifier} successfully created");
+ Console.WriteLine($"{sessionSummary.Identifier}");
}
}
@@ -875,31 +882,31 @@ private static void AddAndProcessMarkers()
}
///
- /// Load data from an SSN file
+ /// This example demonstrates how to load a .ssn file using the FileSessionManager,
+ /// and then request and print sample data for a given Parameter Identifier.
///
private static void LoadSSN()
{
- var fileSessionManager = FileSessionManager.CreateFileSessionManager();
+ // ========= EDITABLE SECTION (tweak these values for your run) =========
+ const string ssnPath = @"";
+ const string parameterIdentifier = "";
+ // =====================================================================
- //var session01 = fileSessionManager.Load(@"C:\Session Location\Session To Load.ssn");
- var session01 = fileSessionManager.Load(@"C:\Session Location\Session To Load.ssn", new List
- {
- @"C:\Session Location\Session To Load.VTS.001.ssv"
- }); // session with associates
+ var fileSessionManager = FileSessionManager.CreateFileSessionManager();
- if (session01 == null)
+ var session = fileSessionManager.Load(ssnPath);
+ if (session == null)
{
- Console.WriteLine("Session not found");
+ Console.WriteLine("Session not found.");
return;
}
-
- var vCarIdentifier = "vCar:Chassis";
- using (var pda = session01.Session.CreateParameterDataAccess(vCarIdentifier))
+
+ using (var pda = session.Session.CreateParameterDataAccess(parameterIdentifier))
{
- pda.GoTo(session01.Session.StartTime + (session01.Session.EndTime - session01.Session.StartTime) / 2);
+ pda.GoTo(session.Session.StartTime + (session.Session.EndTime - session.Session.StartTime) / 2);
var samples = pda.GetNextSamples(10);
- Console.WriteLine($"** Data for {vCarIdentifier}");
+ Console.WriteLine($"** Data for {parameterIdentifier}");
for (var i = 0; i < samples.SampleCount; i++)
{
Console.WriteLine($"{samples.Timestamp[i].ToTimeString()} {samples.Data[i]}");
@@ -907,54 +914,108 @@ private static void LoadSSN()
}
}
- private static void LoadSSNWithAssociatedMerge()
+ ///
+ /// This example loads a Primary session and an Associate session in order to
+ /// create a Composite Session (a session made up of one or more sessions).
+ /// It then retrieves and prints a small number of sample values for a
+ /// specified parameter from both the Primary and the Associate sessions.
+ ///
+ private static void LoadSSNWtihAssociates()
{
- //SQLite ssn style connection string
- ConnectionString = $@"DbEngine=SQLite;Data Source={
- Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
- }\McLaren Applied Technologies\ATLAS 10\SQL Race\IndexingSessionCache.ssn2;";
+ // ========= EDITABLE SECTION (tweak these values for your run) =========
+ const string primarySsnPath = @"";
+ const string associateSsnPath = @"";
+ const string primaryParamId = "";
+ const string associateParamId = "";
+ // =====================================================================
- var qm = QueryManager.CreateQueryManager(ConnectionString);
- qm.SearchOptions = SearchOptions.RetrieveAssociateSessionSummaries;
- // Get the most recent live session from the database
- var sessionSummaries = qm.ExecuteQuery().ToList();
+ var fileSessionManager = FileSessionManager.CreateFileSessionManager();
- var sessionSummary01 =
- sessionSummaries.FirstOrDefault(
- x => x.Identifier == "");
- if (sessionSummary01 == null)
+ var compositeSession = fileSessionManager.LoadCompositeSession(primarySsnPath,new List { associateSsnPath });
+
+ if (compositeSession == null)
{
- Console.WriteLine("Session not found");
+ Console.WriteLine("Failed to create composite session.");
return;
}
- Console.WriteLine("Loading session...");
+ using (var pda = compositeSession.CreateParameterDataAccess(primaryParamId))
+ {
+ pda.GoTo(compositeSession.StartTime + (compositeSession.EndTime - compositeSession.StartTime) / 2);
+ var samples = pda.GetNextSamples(10);
+
+ Console.WriteLine($"** Data for {primaryParamId}");
+ for (var i = 0; i < samples.SampleCount; i++)
+ {
+ Console.WriteLine($"{samples.Timestamp[i].ToTimeString()} {samples.Data[i]}");
+ }
+ }
+
+ using (var pda = compositeSession.CreateParameterDataAccess(associateParamId))
+ {
+ pda.GoTo(compositeSession.StartTime + (compositeSession.EndTime - compositeSession.StartTime) / 2);
+ var samples = pda.GetNextSamples(10);
+
+ Console.WriteLine($"** Data for {associateParamId}");
+ for (var i = 0; i < samples.SampleCount; i++)
+ {
+ Console.WriteLine($"{samples.Timestamp[i].ToTimeString()} {samples.Data[i]}");
+ }
+ }
+ }
+
+ ///
+ /// This example demonstrates how to load a Primary session and an Associate session
+ /// from a SQL backed session database in order to create a Composite Session
+ /// (a session made up of one or more sessions). It then retrieves and prints
+ /// a small number of sample values for a specified parameter from both the
+ /// Primary session and its Associate.
+ ///
+ private static void LoadSqlRaceDatabaseSessionWithAssociates()
+ {
+ // ========= EDITABLE SECTION (tweak these values for your run) =========
+ const string connectionString = @"";
+ const string primarySessionKey = "";
+ const string associateSessionKey = "";
+ const string sessionParamId = "";
+ const string associateParamId = "";
+ // =====================================================================
+
+ ConnectionString = connectionString;
+ var sessionKey = new SessionKey(primarySessionKey);
+ var associateKey = new SessionKey(associateSessionKey);
+
var sessionManager = SessionManager.CreateSessionManager();
- var session01 = sessionManager.Load(sessionSummary01.Key, ConnectionString, new[] { sessionSummary01.Associates.Last() });
- var session = session01.Session;
+ Console.WriteLine("Loading session...");
+ var compositeSession = sessionManager.LoadCompositeSession(
+ sessionKey,
+ ConnectionString,
+ [associateKey]);
Console.WriteLine("Session loaded");
- var muTyreRLIdentifier = "muTyreRL:MRLTyres";
- using (var pda = session01.Session.CreateParameterDataAccess(muTyreRLIdentifier))
+ using (var pda = compositeSession.CreateParameterDataAccess(sessionParamId))
{
- pda.GoTo(session.StartTime + (session.EndTime - session.StartTime) / 2);
+ pda.GoTo(compositeSession.StartTime +
+ (compositeSession.EndTime - compositeSession.StartTime) / 2);
+
var samples = pda.GetNextSamples(10);
- Console.WriteLine($"** Data for {muTyreRLIdentifier}");
+ Console.WriteLine($"** Data for {sessionParamId}");
for (var i = 0; i < samples.SampleCount; i++)
{
Console.WriteLine($"{samples.Timestamp[i].ToTimeString()} {samples.Data[i]}");
}
}
- var vCarIdentifier = "vCar:Chassis";
- using (var pda = session01.Session.CreateParameterDataAccess(vCarIdentifier))
+ using (var pda = compositeSession.CreateParameterDataAccess(associateParamId))
{
- pda.GoTo(session.StartTime + (session.EndTime - session.StartTime) / 2);
+ pda.GoTo(compositeSession.StartTime +
+ (compositeSession.EndTime - compositeSession.StartTime) / 2);
+
var samples = pda.GetNextSamples(10);
- Console.WriteLine($"** Data for {vCarIdentifier}");
+ Console.WriteLine($"** Data for {associateParamId}");
for (var i = 0; i < samples.SampleCount; i++)
{
Console.WriteLine($"{samples.Timestamp[i].ToTimeString()} {samples.Data[i]}");
@@ -962,60 +1023,71 @@ private static void LoadSSNWithAssociatedMerge()
}
}
- private static void CompositeSessionTestWithAppendedSessions()
+ ///
+ /// This example demonstrates how to use QueryManager to retrieve session summaries,
+ /// select a specific session by Identifier, and then load that session together with
+ /// one of its associates as a Composite Session. It then retrieves and prints a small
+ /// number of sample values for a specified parameter from both the Primary session
+ /// and its Associate.
+ ///
+ private static void LoadSessionViaQueryManagerWithAssociate()
{
- ConnectionString = @"Data Source=mesltgs1;Initial Catalog=SQLRACE143;Integrated Security=True";
+ // ========= EDITABLE SECTION (tweak these values for your run) =========
+ const string connectionString = @"";
+ const string sessionIdentifier = "";
+ const string sessionParamId = "";
+ const string associateParamId = "";
+ // =====================================================================
- var compositeSession = new CompositeSession(CompositeSessionKey.NewKey(), "CompositeSessionWithvTagSessionsTest");
+ ConnectionString = connectionString;
var qm = QueryManager.CreateQueryManager(ConnectionString);
- // Get the most recent live session from the database
- var sessionSummaries = qm.ExecuteQuery().ToList();
+ qm.SearchOptions = SearchOptions.RetrieveAssociateSessionSummaries;
- var sessionSummary01 =
- sessionSummaries.FirstOrDefault(
- x => x.Identifier == "");
- if (sessionSummary01 == null)
+ // Discover sessions in the store and find the one we want by human friendly Identifier
+ var sessionSummaries = qm.ExecuteQuery().ToList();
+ var sessionSummary = sessionSummaries.FirstOrDefault(x => x.Identifier == sessionIdentifier);
+ if (sessionSummary == null)
{
Console.WriteLine("Session not found");
return;
}
- var sessionSummary02 =
- sessionSummaries.FirstOrDefault(
- x => x.Identifier == "");
- if (sessionSummary02 == null)
+ if (sessionSummary.Associates == null || sessionSummary.Associates.Count == 0)
{
- Console.WriteLine("Session not found");
+ Console.WriteLine("No associates found for the selected session.");
return;
}
var sessionManager = SessionManager.CreateSessionManager();
- Console.WriteLine("Loading sessions...");
-
- var session01 = sessionManager.Load(sessionSummary01.Key, ConnectionString);
- Console.WriteLine($"Session 1 loaded (start: {session01.Session.StartTime.ToTimeString()} end: {session01.Session.EndTime.ToTimeString()}");
-
- var session02 = sessionManager.Load(sessionSummary02.Key, ConnectionString);
- Console.WriteLine($"Session 2 loaded (start: {session02.Session.StartTime.ToTimeString()} end: {session02.Session.EndTime.ToTimeString()}");
+ Console.WriteLine("Loading session...");
+ var compositeSession = sessionManager.LoadCompositeSession(
+ sessionSummary.Key,
+ ConnectionString,
+ [sessionSummary.Associates.Last()]);
+ Console.WriteLine("Session loaded");
- compositeSession.Add(session01);
- compositeSession.Add(session02);
+ var midpoint = compositeSession.StartTime + (compositeSession.EndTime - compositeSession.StartTime) / 2;
- var parametervCar = session01.Session.GetParameter("vCar:Chassis");
- if (parametervCar == null)
+ using (var pda = compositeSession.CreateParameterDataAccess(sessionParamId))
{
- Console.WriteLine("Parameter not found");
- return;
+ pda.GoTo(midpoint);
+ var samples = pda.GetNextSamples(10);
+
+ Console.WriteLine($"** Data for {sessionParamId}");
+ for (var i = 0; i < samples.SampleCount; i++)
+ {
+ Console.WriteLine($"{samples.Timestamp[i].ToTimeString()} {samples.Data[i]}");
+ }
}
- using (var pda = compositeSession.CreateParameterDataAccess(parametervCar.Identifier))
+ using (var pda = compositeSession.CreateParameterDataAccess(associateParamId))
{
- pda.GoTo(compositeSession.StartTime);
- var samples = pda.GetNextSamples(compositeSession.EndTime);
+ pda.GoTo(midpoint);
+ var samples = pda.GetNextSamples(10);
- Console.WriteLine($"** Data for {parametervCar.Identifier}");
+ Console.WriteLine($"** Data for {associateParamId}");
for (var i = 0; i < samples.SampleCount; i++)
{
Console.WriteLine($"{samples.Timestamp[i].ToTimeString()} {samples.Data[i]}");
@@ -1023,33 +1095,42 @@ private static void CompositeSessionTestWithAppendedSessions()
}
}
- private static void CompositeSessionWithvTagSessionsTest()
+ ///
+ /// This example demonstrates how to load two individual sessions from a SQL backed
+ /// session database, append them into a Composite Session, and then request and
+ /// print sample data for a specified parameter across the combined session range.
+ ///
+ private static void AppendSessions()
{
- //SQLite ssn style connection string
- ConnectionString = @"Data Source=mesltgs1;Initial Catalog=SQLRACE143;Integrated Security=True";
+ // ========= EDITABLE SECTION (tweak these values for your run) =========
+ const string connectionString = @"";
+ const string sessionIdentifier1 = "";
+ const string sessionIdentifier2 = "";
+ const string parameterIdentifier = "";
+ // =====================================================================
- var compositeSession = new CompositeSession(CompositeSessionKey.NewKey(), "CompositeSessionWithvTagSessionsTest");
+ ConnectionString = connectionString;
+ var compositeSession = new CompositeSession(
+ CompositeSessionKey.NewKey(),
+ "CompositeSessionWithvTagSessionsTest");
var qm = QueryManager.CreateQueryManager(ConnectionString);
- // Get the most recent live session from the database
+
+ // Get the most recent live sessions from the database
var sessionSummaries = qm.ExecuteQuery().ToList();
- var sessionSummary01 =
- sessionSummaries.FirstOrDefault(
- x => x.Identifier == "");
+ var sessionSummary01 = sessionSummaries.FirstOrDefault(x => x.Identifier == sessionIdentifier1);
if (sessionSummary01 == null)
{
- Console.WriteLine("Session not found");
+ Console.WriteLine("Session 1 not found");
return;
}
- var sessionSummary02 =
- sessionSummaries.FirstOrDefault(
- x => x.Identifier == "");
+ var sessionSummary02 = sessionSummaries.FirstOrDefault(x => x.Identifier == sessionIdentifier2);
if (sessionSummary02 == null)
{
- Console.WriteLine("Session not found");
+ Console.WriteLine("Session 2 not found");
return;
}
@@ -1058,46 +1139,29 @@ private static void CompositeSessionWithvTagSessionsTest()
Console.WriteLine("Loading sessions...");
var session01 = sessionManager.Load(sessionSummary01.Key, ConnectionString);
- Console.WriteLine("Session loaded");
+ Console.WriteLine($"Session 1 loaded (start: {session01.Session.StartTime.ToTimeString()} end: {session01.Session.EndTime.ToTimeString()})");
var session02 = sessionManager.Load(sessionSummary02.Key, ConnectionString);
- Console.WriteLine("Associated SSV loaded");
+ Console.WriteLine($"Session 2 loaded (start: {session02.Session.StartTime.ToTimeString()} end: {session02.Session.EndTime.ToTimeString()})");
compositeSession.Add(session01);
compositeSession.Add(session02);
- var parameterAero = session02.Session.GetParameter("muTyreRL:MRLTyres");
- if (parameterAero == null)
+ var parameter = session01.Session.GetParameter(parameterIdentifier);
+ if (parameter == null)
{
Console.WriteLine("Parameter not found");
return;
}
- using (var pda = compositeSession.CreateParameterDataAccess(parameterAero.Identifier))
+ using (var pda = compositeSession.CreateParameterDataAccess(parameter.Identifier))
{
- pda.GoTo(compositeSession.StartTime + (compositeSession.EndTime - compositeSession.StartTime) / 2);
- var samples = pda.GetNextSamples(10);
-
- Console.WriteLine($"** Data for {parameterAero.Identifier}");
- for (var i = 0; i < samples.SampleCount; i++)
- {
- Console.WriteLine($"{samples.Timestamp[i].ToTimeString()} {samples.Data[i]}");
- }
- }
-
- var parametervCar = session01.Session.GetParameter("vCar:Chassis");
- if (parametervCar == null)
- {
- Console.WriteLine("Parameter not found");
- return;
- }
+ pda.GoTo(compositeSession.StartTime);
- using (var pda = compositeSession.CreateParameterDataAccess(parametervCar.Identifier))
- {
- pda.GoTo(compositeSession.StartTime + (compositeSession.EndTime - compositeSession.StartTime) / 2);
- var samples = pda.GetNextSamples(10);
+ // Request all samples until the end of the composite session
+ var samples = pda.GetNextSamples(compositeSession.EndTime);
- Console.WriteLine($"** Data for {parametervCar.Identifier}");
+ Console.WriteLine($"** Data for {parameter.Identifier}");
for (var i = 0; i < samples.SampleCount; i++)
{
Console.WriteLine($"{samples.Timestamp[i].ToTimeString()} {samples.Data[i]}");
@@ -1389,6 +1453,96 @@ private static void ReadParameterUnit()
Console.WriteLine();
}
+
+ ///
+ /// This example demonstrates how to build and evaluate a Function that uses parameters
+ /// originating from different sessions when they are loaded together as a Composite Session
+ /// (a session made up of multiple sessions). It loads a primary session together with an
+ /// associate session to form a Composite Session, then creates a Function definition that
+ /// combines the specified parameters. ParameterDataAccess (PDA) objects are created
+ /// for the primary parameter, the associate parameter, and the Function itself. Each PDA is
+ /// used to retrieve samples. The example prints both the raw parameter values and the
+ /// resulting Function values to the console.
+ ///
+ private static void CreateFunctionAcrossMultipleSessionsWithCompositeSession()
+ {
+ // ========= EDITABLE SECTION (tweak these values for your run) =========
+ const string connectionString = @"";
+ const string primarySessionKey = "";
+ const string associateSessionKey = "";
+ const string primarySessionParameterIdentifier = "";
+ const string associateParameterIdentifier = "";
+ // =====================================================================
+
+ ConnectionString = connectionString;
+ var sessionKey = new SessionKey(primarySessionKey);
+ var associateKey = new SessionKey(associateSessionKey);
+
+ var sessionManager = SessionManager.CreateSessionManager();
+
+ Console.WriteLine("Loading session...");
+ var compositeSession = sessionManager.LoadCompositeSession(
+ sessionKey,
+ ConnectionString,
+ [associateKey]);
+ Console.WriteLine("Session loaded");
+
+ // Create & Build Function
+ var functionManager = FunctionManagerFactory.Create();
+ var functionDefinition = FunctionHelper.CreateFdlFunctionDefinition(
+ functionManager,
+ [
+ primarySessionParameterIdentifier,
+ associateParameterIdentifier
+ ]);
+
+ var functionIdentifier = functionDefinition.OutputParameterDefinitions.First().Identifier;
+ var functionPda = compositeSession.CreateParameterDataAccess(functionIdentifier);
+
+ // Get Data
+ var startTime = compositeSession.PrimarySession.LapCollection.FastestLap.StartTime;
+
+ functionPda.GoTo(startTime);
+ var functionSamples = functionPda.GetNextSamples(5);
+ if (functionSamples == null)
+ {
+ Console.WriteLine($"** {functionIdentifier} Failed to get function samples **");
+ return;
+ }
+
+ var primarySessionParameterPda = compositeSession.CreateParameterDataAccess(primarySessionParameterIdentifier);
+ var primarySessionSamples = primarySessionParameterPda.GetNextSamples(5);
+ if (primarySessionSamples == null)
+ {
+ Console.WriteLine($"** {primarySessionParameterIdentifier} Failed to get function samples **");
+ return;
+ }
+
+ var associateParameterIdentifierPda = compositeSession.CreateParameterDataAccess(associateParameterIdentifier);
+ var associateParameterSamples = associateParameterIdentifierPda.GetNextSamples(5);
+ if (associateParameterSamples == null)
+ {
+ Console.WriteLine($"** {associateParameterIdentifier} Failed to get function samples **");
+ return;
+ }
+
+ // Print results
+ // Header
+ Console.WriteLine(" i | P | A | F | F == P + A");
+ Console.WriteLine("----+-------+-------+-------+------------");
+
+ // Body
+ for (var i = 0; i < primarySessionSamples.Data.Length; i++)
+ {
+ var ok = functionSamples.Data[i] == primarySessionSamples.Data[i] + associateParameterSamples.Data[i];
+ Console.WriteLine(
+ $"{i,2} | {primarySessionSamples.Data[i],5} | {associateParameterSamples.Data[i],5} | {functionSamples.Data[i],5} | {(ok ? "✓" : "✗")} ({functionSamples.Data[i]} {(ok ? "=" : "≠")} {primarySessionSamples.Data[i]}+{associateParameterSamples.Data[i]})"
+ );
+ }
+
+ Console.WriteLine("");
+ }
+
private static void Session_LapStarted(object sender, LapEventArgs e)
{
Console.WriteLine($"Lap started {e.Lap.Name}");