public void ShouldPushOutputDataConfigurationToStimuli() { var e = new Epoch(UNUSED_PROTOCOL_ID); var dev = new UnitConvertingExternalDevice("name", "co", new Measurement(0m, "units")); const string units = "units"; var data = new OutputData(Enumerable.Repeat(new Measurement(0, units), 100), new Measurement(10, "Hz")); var s = new RenderedStimulus((string)"stimID", (IDictionary <string, object>) new Dictionary <string, object>(), (IOutputData)data); e.Stimuli[dev] = s; var configuration = new List <IPipelineNodeConfiguration>(); var config = new Dictionary <string, object>(); config["key"] = "value"; configuration.Add(new PipelineNodeConfiguration("NODE1", config)); var outputTime = DateTimeOffset.Now; e.DidOutputData(dev, outputTime, data.Duration, configuration); var expected = configuration; Assert.That(e.Stimuli[dev].OutputConfigurationSpans.First().Nodes, Is.EqualTo(expected)); Assert.That(e.Stimuli[dev].OutputConfigurationSpans.First().Time, Is.EqualTo(data.Duration)); }
public void ShouldNotPersistEpochGivenNullPersistor() { var c = new Controller(); bool evt = false; c.DAQController = new TestDAQController(); c.Clock = c.DAQController as IClock; c.DiscardedEpoch += (co, args) => Assert.Fail("Run failed"); var dev = new UnitConvertingExternalDevice(UNUSED_DEVICE_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND) { Controller = c, MeasurementConversionTarget = "V" }; var outStream = new DAQOutputStream("outStream") { MeasurementConversionTarget = "V" }; var inStream = new DAQInputStream("inStream") { MeasurementConversionTarget = "V" }; (c.DAQController as IMutableDAQController).AddStream(outStream); (c.DAQController as IMutableDAQController).AddStream(inStream); var srate = new Measurement(10, "Hz"); outStream.SampleRate = srate; inStream.SampleRate = srate; dev.BindStream(outStream); dev.BindStream(inStream); var e = new Epoch(UNUSED_PROTOCOL); var samples = new List <IMeasurement> { new Measurement(1.0m, "V"), new Measurement(1.0m, "V"), new Measurement(1.0m, "V") }; var data = new OutputData(samples, srate, true); e.Stimuli[dev] = new RenderedStimulus((string)"stimID", (IDictionary <string, object>) new Dictionary <string, object>(), (IOutputData)data); e.Responses[dev] = new Response(); e.Background[dev] = new Epoch.EpochBackground(new Measurement(0, "V"), srate); ((TestDAQController)c.DAQController).AddStreamMapping(outStream, inStream); c.RunEpoch(e, null); Assert.Pass(); }
public void ShouldSurfaceExceptionInPersistorTask() { var c = new Controller(); bool evt = false; c.DAQController = new TestDAQController(); c.Clock = c.DAQController as IClock; var persistor = new AggregateExceptionThrowingEpochPersistor(); c.SavedEpoch += (co, args) => { evt = true; }; var dev = new UnitConvertingExternalDevice(UNUSED_DEVICE_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND) { Controller = c, MeasurementConversionTarget = "V" }; var outStream = new DAQOutputStream("outStream") { MeasurementConversionTarget = "V" }; var inStream = new DAQInputStream("inStream") { MeasurementConversionTarget = "V" }; (c.DAQController as IMutableDAQController).AddStream(outStream); (c.DAQController as IMutableDAQController).AddStream(inStream); var srate = new Measurement(10, "Hz"); outStream.SampleRate = srate; inStream.SampleRate = srate; dev.BindStream(outStream); dev.BindStream(inStream); var e = new Epoch(UNUSED_PROTOCOL); var samples = new List <IMeasurement> { new Measurement(1.0m, "V"), new Measurement(1.0m, "V"), new Measurement(1.0m, "V") }; var data = new OutputData(samples, srate, true); e.Stimuli[dev] = new RenderedStimulus((string)"stimID", (IDictionary <string, object>) new Dictionary <string, object>(), (IOutputData)data); e.Responses[dev] = new Response(); e.Background[dev] = new Epoch.EpochBackground(new Measurement(0, "V"), srate); ((TestDAQController)c.DAQController).AddStreamMapping(outStream, inStream); Assert.That(() => c.RunEpoch(e, persistor), Throws.TypeOf <SymphonyControllerException>()); }
public void OutputData_DataWithStreamConfigFailsWithNonNullExistingConfig() { IOutputData data = new OutputData(this.Data, UNUSED_SRATE, false) .DataWithStreamConfiguration(streamFake, new Dictionary <string, object>()); Assert.Throws <ExistingConfigurationException>( () => data.DataWithStreamConfiguration(streamFake, new Dictionary <string, object>())); }
public void HasOutputTime() { IOutputData data = new OutputData(Data, UNUSED_SRATE, false); Assert.False(data.HasOutputTime); data.OutputTime = DateTimeOffset.Now; Assert.True(data.HasOutputTime); }
public void TestOutputDataHasNodeConfiguration() { IOutputData outData = new OutputData(Data, UNUSED_SRATE, false); Assert.False(outData.HasNodeConfiguration(devFake.Name)); outData = outData.DataWithExternalDeviceConfiguration(devFake, new Dictionary <string, object>()); Assert.True(outData.HasNodeConfiguration(devFake.Name)); }
public void FiresStimulusOutputEvents() { var c = new TestDAQController(); var srate = new Measurement(10, "Hz"); var outStream = new DAQOutputStream("out") { MeasurementConversionTarget = "V", SampleRate = srate }; var inStream = new DAQInputStream("in") { MeasurementConversionTarget = "V", SampleRate = srate }; var outputData = new Dictionary <IDAQOutputStream, Queue <IOutputData> >(); var dataQueue = new Queue <IOutputData>(); var outputIOData = new OutputData( Enumerable.Range(0, 100).Select(i => new Measurement(i, "V")), new Measurement(10, "Hz") ); dataQueue.Enqueue(outputIOData); outputData[outStream] = dataQueue; var dev = new TestDevice("test", outputData) { MeasurementConversionTarget = "V" }; dev.BindStream(outStream); bool fired = false; c.StimulusOutput += (daq, args) => { Assert.That(args.Stream == outStream); Assert.That(args.Data != null); Assert.That(args.Data.Configuration.Count() > 0); fired = true; }; c.ProcessIteration += (daq, args) => ((IDAQController)daq).RequestStop(); c.AddStreamMapping(outStream, inStream); c.Start(false); while (c.Running) { ; } Assert.That(fired, Is.True.After(1000, 10)); }
public void OutputData_SetsStreamConfig() { var config = new Dictionary <string, object>(); IOutputData data = new OutputData(Data, UNUSED_SRATE, false); data = data.DataWithStreamConfiguration(streamFake, config); Assert.That(data.NodeConfigurationWithName(streamFake.Name).Configuration, Is.EqualTo(config)); }
public void OutputPipelineContinuity( [Values(1000, 5000, 10000, 15000, 20000)] double sampleRate, [Values(0.1, 0.5, 1, 5)] double blockDurationSeconds ) { const double epochDuration = 2; //seconds var srate = new Measurement((decimal) sampleRate, "Hz"); var daq = new TestDAQController(); var outStream = new DAQOutputStream("OUT") { SampleRate = srate, MeasurementConversionTarget = "V" }; var controller = new Controller() { Clock = daq, DAQController = daq }; var dev = new UnitConvertingExternalDevice("dev", "co", controller, new Measurement(0, "V")) { Clock = daq, MeasurementConversionTarget = "V" }; dev.BindStream(outStream); // Setup Epoch var e = new Epoch("OutputPipelineContinuity"); var nSamples = (int)TimeSpan.FromSeconds(epochDuration).Samples(srate); IList<IMeasurement> stimData = (IList<IMeasurement>) Enumerable.Range(0, nSamples) .Select(i => new Measurement((decimal) (8 * Math.Sin(((double)i) / (nSamples / 10.0))), "V") as IMeasurement) .ToList(); IOutputData stimOutputData = new OutputData(stimData, srate); var stim = new RenderedStimulus((string) "RenderedStimulus", (IDictionary<string, object>) new Dictionary<string, object>(), stimOutputData); e.Stimuli[dev] = stim; e.Responses[dev] = new Response(); e.Background[dev] = new Epoch.EpochBackground(new Measurement(0, "V"), srate); controller.EnqueueEpoch(e); controller.NextEpoch(); var blockSpan = TimeSpan.FromSeconds(blockDurationSeconds); foreach (var stimBlock in stim.DataBlocks(blockSpan)) { var cons = stimOutputData.SplitData(blockSpan); var expected = cons.Head.Data; stimOutputData = cons.Rest; Assert.That(stimBlock.Data, Is.EqualTo(expected)); } }
public void HoldsStimulusID() { var parameters = new Dictionary <string, object>(); const string stimID = "my.ID"; var measurements = new List <IMeasurement> { new Measurement(1, "V") }; var data = new OutputData(measurements, new Measurement(1, "Hz"), false); var s = new RenderedStimulus((string)stimID, (IDictionary <string, object>)parameters, (IOutputData)data); Assert.That(s.StimulusID, Is.EqualTo(stimID)); }
public void ShouldThrowForUnitMismatch() { const double sampleRateHz = 100d; var parameters = new Dictionary <string, object>(); var sampleRate = new Measurement((decimal)sampleRateHz, "Hz"); IOutputData data = new OutputData(Enumerable.Range(0, (int)TimeSpan.FromSeconds(3).Samples(new Measurement((decimal)sampleRateHz, "Hz"))) .Select(i => new Measurement(i, i > 1 ? "other" : "first")).ToList(), sampleRate, false); Assert.That(() => new RenderedStimulus("RenderedStimulus", parameters, data), Throws.TypeOf(typeof(MeasurementIncompatibilityException))); }
public void OutputDataChainsIsLast() { IMeasurement srate = new Measurement(1000, "Hz"); IOutputData data1 = new OutputData(this.Data, srate, false); Assert.AreEqual(data1.IsLast, new OutputData(data1, data1.Data).IsLast); IOutputData data2 = new OutputData(this.Data, srate, true); Assert.AreEqual(data2.IsLast, new OutputData(data2, data2.Data).IsLast); }
public void ConcatThrowsForSampleRateMismatch() { var srate1 = new Measurement(1000, "Hz"); var srate2 = new Measurement(100, "Hz"); IOutputData outData1 = new OutputData(this.Data, srate1, false); IOutputData outData2 = new OutputData(this.Data, srate2, false); Assert.Throws <ArgumentException>(() => outData1.Concat(outData2)); Assert.Throws <ArgumentException>(() => outData2.Concat(outData1)); }
public void OutputDataSplitDataReturnsEntireDataForOverDuration() { IDictionary <string, object> config = new Dictionary <string, object>(); var srate = new Measurement(1000, "Hz"); IOutputData outData = new OutputData(this.Data, srate, false); var duration = new TimeSpan(1, 0, 0); //1 hr var result = outData.SplitData(duration); Assert.AreEqual(outData.Data, result.Head.Data); Assert.AreEqual(0, result.Rest.Duration.Ticks); }
public void HoldsParameters() { var parameters = new Dictionary <string, object>(); parameters["key1"] = "value1"; parameters["key2"] = 2; var measurements = new List <IMeasurement> { new Measurement(1, "V") }; var data = new OutputData(measurements, new Measurement(1, "Hz"), false); var s = new RenderedStimulus((string)"RenderedStimulus", (IDictionary <string, object>)parameters, (IOutputData)data); Assert.That(s.Parameters, Is.EqualTo(parameters)); }
public void ConcatSetsIsLast() { IMeasurement srate = new Measurement(1000, "Hz"); IOutputData outData1 = new OutputData(this.Data, srate, false); IOutputData outData2 = new OutputData(this.Data, srate, true); Assert.That(outData1.IsLast, Is.Not.EqualTo(outData2.IsLast)); Assert.That(outData1.Concat(outData1).IsLast, Is.EqualTo(outData1.IsLast)); Assert.That(outData2.Concat(outData2).IsLast, Is.EqualTo(outData2.IsLast)); Assert.That(outData1.Concat(outData2).IsLast, Is.True); Assert.That(outData2.Concat(outData1).IsLast, Is.True); }
public void MarksAsNotLastIfMoreBlocks() { var parameters = new Dictionary <string, object>(); var sampleRate = new Measurement(1000, "Hz"); IOutputData data = new OutputData(Enumerable.Range(0, 1000).Select(i => new Measurement(i, "units")).ToList(), sampleRate, true); var s = new RenderedStimulus((string)"RenderedStimulus", (IDictionary <string, object>)parameters, data); var block = TimeSpan.FromMilliseconds(100); IEnumerator <IOutputData> iter = s.DataBlocks(block).GetEnumerator(); Assert.True(iter.MoveNext()); Assert.False(iter.Current.IsLast); }
public void ConcatenatesOutputData() { IMeasurement srate = new Measurement(1000, "Hz"); IOutputData outData1 = new OutputData(this.Data, srate, false); IOutputData outData2 = new OutputData(this.Data.Concat(this.Data).ToList(), srate, true); var actual = outData1.Concat(outData2); var expectedData = this.Data.Concat(this.Data).Concat(this.Data).ToList(); Assert.That(actual.Data, Is.EqualTo(expectedData)); Assert.That(actual.SampleRate, Is.EqualTo(srate)); }
public void ConcatThrowsWithEitherStreamConfiguration() { IMeasurement srate = new Measurement(1000, "Hz"); IOutputData outData1 = new OutputData(this.Data, srate, false); IOutputData outData2 = new OutputData(this.Data, srate, false); Assert.DoesNotThrow(() => outData1.Concat(outData2)); var outData3 = outData1.DataWithStreamConfiguration(streamFake, new Dictionary <string, object>()); Assert.Throws <ArgumentException>(() => outData3.Concat(outData2)); Assert.Throws <ArgumentException>(() => outData2.Concat(outData3)); }
public void OutputDataChainsConfiguration() { IDictionary <string, object> config = new Dictionary <string, object>(2); config["param1"] = 10; config["param2"] = 1; IMeasurement srate = new Measurement(1000, "Hz"); IOutputData data1 = new OutputData(this.Data, srate, false); IOutputData data2 = new OutputData(data1, data1.Data); Assert.IsNotNull(data2); Assert.AreEqual(data1.Data, data2.Data); Assert.AreEqual(data1.SampleRate, data2.SampleRate); }
public void PullOutputDataShouldReturnNullWithNullCurrentEpoch() { Controller c = new Controller(); IExternalDevice dev = new UnitConvertingExternalDevice(UNUSED_DEVICE_NAME, UNUSED_DEVICE_MANUFACTURER, c, UNUSED_BACKGROUND); IList <IMeasurement> data = (IList <IMeasurement>)Enumerable.Range(0, 1000).Select(i => new Measurement(i, "V") as IMeasurement).ToList(); var sampleRate = new Measurement(1000, "Hz"); IOutputData data1 = new OutputData(data, sampleRate, false); var e = new Epoch(""); e.Stimuli[dev] = new RenderedStimulus((string)"RenderedStimulus", (IDictionary <string, object>) new Dictionary <string, object>(), data1); e.Background[dev] = new Epoch.EpochBackground(new Measurement(0, "V"), sampleRate); Assert.Null(c.PullOutputData(dev, TimeSpan.FromSeconds(1))); }
public void ConcatThrowsWithEitherExternalDeviceConfiguration() { IMeasurement srate = new Measurement(1000, "Hz"); IOutputData outData1 = new OutputData(this.Data, srate, false); IOutputData outData2 = new OutputData(this.Data, srate, false); Assert.DoesNotThrow(() => outData1.Concat(outData2)); var dev = new UnitConvertingExternalDevice("DevName", "DevManufacturer", new Measurement(0, "V")); var outData3 = outData1.DataWithExternalDeviceConfiguration(dev, new Dictionary <string, object>()); Assert.Throws <ArgumentException>(() => outData3.Concat(outData2)); Assert.Throws <ArgumentException>(() => outData2.Concat(outData3)); }
private IOutputData BackgroundDataForDevice(IExternalDevice dev, TimeSpan blockDuration) { //log.DebugFormat("Presenting Epoch background for {0}.", dev.Name); if (!Background.ContainsKey(dev)) { throw new ArgumentException("Epoch does not have a stimulus or background for " + dev.Name); } //Calculate background var srate = Background[dev].SampleRate; var value = Background[dev].Background; IOutputData result = new OutputData(ConstantMeasurementList(blockDuration, srate, value), srate, false); return(result); }
public void PullsOutputData() { var c = new Controller(); IExternalDevice dev = new UnitConvertingExternalDevice(UNUSED_DEVICE_NAME, UNUSED_DEVICE_MANUFACTURER, c, UNUSED_BACKGROUND); const int srate = 1000; IList <IMeasurement> data = (IList <IMeasurement>)Enumerable.Range(0, srate * 2).Select(i => new Measurement(i, "V") as IMeasurement).ToList(); var sampleRate = new Measurement(srate, "Hz"); IOutputData data1 = new OutputData(data, sampleRate, false); var e = new Epoch(""); e.Stimuli[dev] = new RenderedStimulus((string)"RenderedStimulus", (IDictionary <string, object>) new Dictionary <string, object>(), data1); e.Background[dev] = new Epoch.EpochBackground(new Measurement(0, "V"), sampleRate); c.EnqueueEpoch(e); TimeSpan d1 = TimeSpan.FromSeconds(0.75); c.EnqueueEpoch(e); c.NextEpoch(); var pull1 = c.PullOutputData(dev, d1); var pull2 = c.PullOutputData(dev, d1); var samples = (int)d1.Samples(new Measurement(srate, "Hz")); Assert.AreEqual(data.Take(samples).ToList(), pull1.Data); Assert.AreEqual(data.Skip(samples).Take(samples).ToList(), pull2.Data); var pull3 = c.PullOutputData(dev, d1); Assert.AreEqual(data.Skip(2 * samples) .Take(samples) .Concat(Enumerable.Range(0, srate - samples).Select(i => e.Background[dev].Background)) .ToList(), pull3.Data); }
public void OutputDataCreation() { IDictionary <string, object> config = new Dictionary <string, object>(2); config["param1"] = 10; config["param2"] = 1; IMeasurement srate = new Measurement(1000, "Hz"); IOutputData outData = new OutputData(this.Data, srate, false); Assert.IsNotNull(outData); Assert.AreEqual(this.Data, outData.Data); Assert.IsNull(outData.NodeConfigurationWithName(IOData.EXTERNAL_DEVICE_CONFIGURATION_NAME)); Assert.IsNull(outData.NodeConfigurationWithName(IOData.STREAM_CONFIGURATION_NAME)); Assert.AreEqual(srate, outData.SampleRate); Assert.False(outData.IsLast); }
public void OutputTimeThrowsUntilSet() { IDictionary <string, object> config = new Dictionary <string, object>(2); config["param1"] = 10; config["param2"] = 1; IMeasurement srate = new Measurement(1000, "Hz"); IOutputData outData = new OutputData(this.Data, srate, false); Assert.Throws <InvalidOperationException>(() => outData.OutputTime = outData.OutputTime); DateTimeOffset expectedTime = DateTimeOffset.UtcNow; outData.OutputTime = expectedTime; Assert.AreEqual(expectedTime, outData.OutputTime); }
private static void OutputStreamFixture(out IList <IOutputData> data, out DAQOutputStream s, int numData) { data = new List <IOutputData>(3); var measurements = new List <IMeasurement>(2) { new Measurement(1, "V"), new Measurement(2, "V") }; var sampleRate = new Measurement(1000, "Hz"); for (int i = 0; i < numData; i++) { bool last = i == numData - 1 ? true : false; IOutputData outputData = new OutputData(measurements, sampleRate, last); data.Add(outputData); } s = new DAQOutputStream("OUT") { MeasurementConversionTarget = measurements.First().BaseUnit, SampleRate = sampleRate }; var outData = new Dictionary <IDAQOutputStream, Queue <IOutputData> >(1); outData[s] = new Queue <IOutputData>(data); var outDevice = new TestDevice("OUT-DEVICE", outData) { Controller = new Controller(), MeasurementConversionTarget = "V" }; s.Device = outDevice; }
/// <summary> /// Matlab-friendly factory method to run a single Epoch. /// </summary> /// <remarks>Constructs an Epoch with homogenous stimulus ID, sample rate and units, then runs the /// constructed Epoch. /// </remarks> /// /// <param name="protocolID">Protocol ID of the constructed Epoch</param> /// <param name="parameters">Protocol parameters of the constructed Epoch</param> /// <param name="stimulusID">Stimulus plugin ID for all constructed stimuli</param> /// <param name="stimulusSampleRate">Simulus sample rate for all constructed stimuli</param> /// <param name="stimuli">Simulus data for output devices</param> /// <param name="backgrounds">Backgrounds for output devices</param> /// <param name="responses">Devices from which to record Responses</param> /// <param name="persistor">EpochPersistor to persist Epoch</param> public void RunEpoch( string protocolID, IDictionary <string, object> parameters, string stimulusID, Measurement stimulusSampleRate, IDictionary <ExternalDeviceBase, IEnumerable <IMeasurement> > stimuli, IDictionary <ExternalDeviceBase, IMeasurement> backgrounds, IEnumerable <ExternalDeviceBase> responses, EpochPersistor persistor) { var epoch = new Epoch(protocolID, parameters); foreach (var dev in stimuli.Keys) { var data = new OutputData(stimuli[dev], stimulusSampleRate, true); var stim = new RenderedStimulus(stimulusID, (IDictionary <string, object>) new Dictionary <string, object> { { "data", data } }, (IOutputData)data); epoch.Stimuli[dev] = stim; } foreach (var dev in responses) { epoch.Responses[dev] = new Response(); } foreach (var dev in backgrounds.Keys) { epoch.Background[dev] = new Epoch.EpochBackground(backgrounds[dev], stimulusSampleRate); } RunEpoch(epoch, persistor); }
public void InputDataConversionViaProc() { IDictionary <string, object> config = new Dictionary <string, object>(2); config["param1"] = 10; config["param2"] = 1; IMeasurement srate = new Measurement(1000, "Hz"); IOutputData outData = new OutputData(this.Data, srate, false) .DataWithExternalDeviceConfiguration(devFake, new Dictionary <string, object>()) .DataWithStreamConfiguration(streamFake, new Dictionary <string, object>()); outData.OutputTime = DateTimeOffset.Now; Converters.Clear(); ConvertProc fooConversion = (m) => new Measurement(m.QuantityInBaseUnit * 10, 1, "foo"); Converters.Register("V", "foo", fooConversion); IOutputData expected = new OutputData(outData, outData.Data.Select(m => new Measurement(m.QuantityInBaseUnit * 10, 1, "foo")).ToList()) { OutputTime = outData.OutputTime }; IOutputData actual = outData.DataWithConversion((m) => new Measurement(m.QuantityInBaseUnit * 10, 1, "foo")); Assert.AreEqual(expected.Data, actual.Data); Assert.AreEqual(expected.NodeConfigurationWithName(IOData.EXTERNAL_DEVICE_CONFIGURATION_NAME), actual.NodeConfigurationWithName(IOData.EXTERNAL_DEVICE_CONFIGURATION_NAME)); Assert.AreEqual(expected.NodeConfigurationWithName(IOData.STREAM_CONFIGURATION_NAME), actual.NodeConfigurationWithName(IOData.STREAM_CONFIGURATION_NAME)); Assert.AreEqual(expected.OutputTime, actual.OutputTime); }
public void ShouldSupplyEpochBackgroundForExternalDevicesWithoutStimuli() { var c = new Controller(); var dev1 = new UnitConvertingExternalDevice("dev1", "co", c, new Measurement(0, "V")); var dev2 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V")); int baseSamples = 1000; IList <IMeasurement> data = (IList <IMeasurement>)Enumerable.Range(0, baseSamples) .Select(i => new Measurement(i, "V") as IMeasurement) .ToList(); Measurement sampleRate = new Measurement(baseSamples, "Hz"); var config = new Dictionary <string, object>(); IOutputData data1 = new OutputData(data, sampleRate, true); var e = new Epoch(""); e.Stimuli[dev1] = new RenderedStimulus((string)"RenderedStimulus", (IDictionary <string, object>)config, data1); var backgroundMeasurement = new Measurement(3.2m, "V"); e.Background[dev2] = new Epoch.EpochBackground(backgroundMeasurement, sampleRate); c.EnqueueEpoch(e); c.NextEpoch(); var out1 = c.PullOutputData(dev1, e.Duration); Assert.NotNull(out1); var out2 = c.PullOutputData(dev2, e.Duration); Assert.NotNull(out2); Assert.AreEqual((TimeSpan)e.Duration, out2.Duration); Assert.AreEqual(backgroundMeasurement, out2.Data.First()); }