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 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 ExternalDeviceStreams() { var ed = new UnitConvertingExternalDevice("TestDevice", UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND); DAQInputStream in0 = new DAQInputStream("In-0"); DAQOutputStream out0 = new DAQOutputStream("Out-0"); ed.BindStream(in0).BindStream(out0); Assert.IsTrue(ed.Streams.ContainsKey(in0.Name)); Assert.IsTrue(in0.Devices.Contains(ed)); Assert.IsTrue(ed.Streams.ContainsKey(out0.Name)); Assert.IsTrue(out0.Device == ed); ed.UnbindStream("In-0"); Assert.IsFalse(ed.Streams.ContainsKey(in0.Name)); Assert.IsFalse(in0.Devices.Contains(ed)); Assert.IsTrue(ed.Streams.ContainsKey(out0.Name)); Assert.IsTrue(out0.Device == ed); ed.UnbindStream("Out-0"); Assert.IsFalse(ed.Streams.ContainsKey(in0.Name)); Assert.IsFalse(in0.Devices.Contains(ed)); Assert.IsFalse(ed.Streams.ContainsKey(out0.Name)); Assert.IsFalse(out0.Device == ed); }
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 inStream = new DAQInputStream("IN") { 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", OutputSampleRate = srate, InputSampleRate = srate }; dev.BindStream(outStream).BindStream(inStream); // 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.Backgrounds[dev] = new Background(new Measurement(0, "V"), srate); controller.EnqueueEpoch(e); 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 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 ShouldRaiseExceptionIfPullingLessThanOneSample() { var e = new UnitConvertingExternalDevice(UNUSED_NAME, null, new Measurement(0, "V")); var stream = new DAQOutputStream(UNUSED_NAME); e.BindStream(stream); stream.SampleRate = new Measurement(1, "Hz"); Assert.Throws <ExternalDeviceException>(() => e.PullOutputData(stream, TimeSpan.FromMilliseconds(0.1))); }
public void ShouldConvertBackgoundUnits() { Converters.Register("xfromUnits", "toUnits", m => new Measurement(2 * m.Quantity, m.Exponent, m.BaseUnit)); var bg = new Measurement(1, "xfromUnits"); var e = new UnitConvertingExternalDevice(UNUSED_NAME, null, bg) { MeasurementConversionTarget = "toUnits" }; var stream = new DAQOutputStream(UNUSED_NAME); e.BindStream(stream); var expected = new Measurement(bg.Quantity * 2, bg.Exponent, bg.BaseUnit); Assert.That(e.OutputBackground, Is.EqualTo(expected)); }
public void ShouldConvertBackgoundUnits() { Converters.Register("xfromUnits", "toUnits", m => new Measurement(2 * m.Quantity, m.Exponent, m.BaseUnit)); var bg = new Measurement(1, "xfromUnits"); var e = new UnitConvertingExternalDevice(UNUSED_NAME, null, bg) { MeasurementConversionTarget = "toUnits" }; var stream = new DAQOutputStream(UNUSED_NAME); e.BindStream(stream); var expected = new Measurement(bg.Quantity * 2, bg.Exponent, bg.BaseUnit); Assert.That(e.OutputBackground, Is.EqualTo(expected)); }
public void RenderedStimulus( [Values(1000, 10000, 20000, 50000)] double sampleRate, [Values(2)] int nEpochs ) { Converters.Clear(); Converters.Register("V", "V", // just an identity conversion for now, to pass Validate() (IMeasurement m) => m); HekaDAQInputStream.RegisterConverters(); HekaDAQOutputStream.RegisterConverters(); Assert.That(HekaDAQController.AvailableControllers().Count(), Is.GreaterThan(0)); foreach (var daq in HekaDAQController.AvailableControllers()) { const double epochDuration = 5; //s daq.InitHardware(); try { daq.SampleRate = new Measurement((decimal)sampleRate, "Hz"); var controller = new Controller { Clock = daq.Clock, DAQController = daq }; var dev0 = new UnitConvertingExternalDevice("Device0", "Manufacturer", controller, new Measurement(0, "V")) { MeasurementConversionTarget = "V", Clock = daq.Clock, OutputSampleRate = daq.SampleRate, InputSampleRate = daq.SampleRate }; dev0.BindStream((IDAQOutputStream)daq.GetStreams("ao0").First()); dev0.BindStream((IDAQInputStream)daq.GetStreams("ai0").First()); var dev1 = new UnitConvertingExternalDevice("Device1", "Manufacturer", controller, new Measurement(0, "V")) { MeasurementConversionTarget = "V", Clock = daq.Clock, OutputSampleRate = daq.SampleRate, InputSampleRate = daq.SampleRate }; dev1.BindStream((IDAQOutputStream)daq.GetStreams("ao1").First()); dev1.BindStream((IDAQInputStream)daq.GetStreams("ai1").First()); for (int j = 0; j < nEpochs; j++) { // Setup Epoch var e = new Epoch("HekaIntegration" + j); var nSamples = (int)TimeSpan.FromSeconds(epochDuration).Samples(daq.SampleRate); 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(); e.Stimuli[dev0] = new RenderedStimulus((string) "RenderedStimulus", (IDictionary<string, object>) new Dictionary<string, object>(), (IOutputData) new OutputData(stimData, daq.SampleRate)); e.Responses[dev0] = new Response(); e.Stimuli[dev1] = new RenderedStimulus((string) "RenderedStimulus", (IDictionary<string, object>) new Dictionary<string, object>(), (IOutputData) new OutputData(Enumerable.Range(0, nSamples) .Select(i => new Measurement((decimal)(8 * Math.Sin(((double)i) / (nSamples / 10.0))), "V")) .ToList(), daq.SampleRate)); e.Responses[dev1] = new Response(); //Run single epoch var fakeEpochPersistor = new FakeEpochPersistor(); controller.RunEpoch(e, fakeEpochPersistor); Assert.That((bool)e.StartTime, Is.True); Assert.That((DateTimeOffset)e.StartTime, Is.LessThanOrEqualTo(controller.Clock.Now)); Assert.That(e.Responses[dev0].Duration, Is.EqualTo(((TimeSpan)e.Duration)) .Within(TimeSpanExtensions.FromSamples(1, daq. SampleRate))); Assert.That(e.Responses[dev1].Duration, Is.EqualTo(((TimeSpan)e.Duration)) .Within(TimeSpanExtensions.FromSamples(1, daq. SampleRate))); Assert.That(fakeEpochPersistor.PersistedEpochs, Contains.Item(e)); var failures0 = e.Responses[dev0].Data.Select( (t, i) => new { index = i, diff = t.QuantityInBaseUnits - stimData[i].QuantityInBaseUnits }) .Where(dif => Math.Abs(dif.diff) > (decimal)MAX_VOLTAGE_DIFF); foreach (var failure in failures0.Take(10)) Console.WriteLine("{0}: {1}", failure.index, failure.diff); /* * According to Telly @ Heka, a patch cable may introduce 3-4 offset points */ Assert.That(failures0.Count(), Is.LessThanOrEqualTo(4)); /* //Since we only have one patch cable on the test rig, //we're not checking second device response values var failures1 = e.Responses[dev1].Data.Data.Select( (t, i) => new { index = i, diff = t.QuantityInBaseUnit - stimData[i].QuantityInBaseUnit }) .Where(dif => Math.Abs(dif.diff) > MAX_VOLTAGE_DIFF); foreach (var failure in failures1.Take(10)) Console.WriteLine("{0}: {1}", failure.index, failure.diff); Assert.That(failures1.Count(), Is.EqualTo(0)); */ } } finally { if (daq.IsHardwareReady) daq.CloseHardware(); } } }
public void ContinuousAcquisition( [Values(1000, 10000, 20000, 50000)] double sampleRate, [Values(20)] int nEpochs) { Converters.Clear(); HekaDAQInputStream.RegisterConverters(); HekaDAQOutputStream.RegisterConverters(); Assert.That(HekaDAQController.AvailableControllers().Count(), Is.GreaterThan(0)); foreach (var daq in HekaDAQController.AvailableControllers()) { const double epochDuration = 1; //s try { daq.InitHardware(); daq.SampleRate = new Measurement((decimal)sampleRate, "Hz"); var controller = new Controller { Clock = daq.Clock, DAQController = daq }; var dev0 = new UnitConvertingExternalDevice("Device0", "Manufacturer", controller, new Measurement(0, "V")) { MeasurementConversionTarget = "V", Clock = daq.Clock, OutputSampleRate = daq.SampleRate, InputSampleRate = daq.SampleRate }; dev0.BindStream((IDAQOutputStream)daq.GetStreams("ao0").First()); dev0.BindStream((IDAQInputStream)daq.GetStreams("ai0").First()); var dev1 = new UnitConvertingExternalDevice("Device1", "Manufacturer", controller, new Measurement(0, "V")) { MeasurementConversionTarget = "V", Clock = daq.Clock, OutputSampleRate = daq.SampleRate, InputSampleRate = daq.SampleRate }; dev1.BindStream((IDAQOutputStream)daq.GetStreams("ao1").First()); dev1.BindStream((IDAQInputStream)daq.GetStreams("ai1").First()); var nDAQStarts = 0; daq.Started += (evt, args) => { nDAQStarts++; }; var completedEpochs = new Queue<Epoch>(); controller.CompletedEpoch += (evt, args) => { completedEpochs.Enqueue(args.Epoch); if (completedEpochs.Count >= nEpochs) { controller.RequestStop(); } }; var epochs = new Queue<Epoch>(); var nSamples = (int)TimeSpan.FromSeconds(epochDuration).Samples(daq.SampleRate); // Triangle wave var data = Enumerable.Range(0, nSamples/2) .Select(k => new Measurement(k/(nSamples/2.0/10.0), "V") as IMeasurement) .ToList(); var stimData = data.Concat(Enumerable.Reverse(data)).ToList(); var fakeEpochPersistor = new FakeEpochPersistor(); bool start = true; for (int j = 0; j < nEpochs; j++) { var e = new Epoch("HekaIntegration" + j); e.Stimuli[dev0] = new RenderedStimulus("Stim", new Dictionary<string, object>(), new OutputData(stimData, daq.SampleRate)); e.Responses[dev0] = new Response(); e.SetBackground(dev1, new Measurement(1, "V"), daq.SampleRate); e.Responses[dev1] = new Response(); epochs.Enqueue(e); controller.EnqueueEpoch(e); if (start) { controller.StartAsync(fakeEpochPersistor); start = false; } } while (controller.IsRunning) { Thread.Sleep(1); } controller.WaitForCompletedEpochTasks(); var stopTime = controller.Clock.Now; Assert.That(nDAQStarts <= 1, "Epochs did not run continuously"); Assert.AreEqual(epochs, completedEpochs); Assert.AreEqual(fakeEpochPersistor.PersistedEpochs, completedEpochs); DateTimeOffset prevTime = completedEpochs.First().StartTime; foreach (var e in completedEpochs) { Assert.That((bool)e.StartTime, Is.True); Assert.That((DateTimeOffset)e.StartTime, Is.GreaterThanOrEqualTo(prevTime)); Assert.That((DateTimeOffset)e.StartTime, Is.LessThanOrEqualTo(stopTime)); Assert.That(e.Responses[dev0].Duration, Is.EqualTo(((TimeSpan)e.Duration)) .Within(TimeSpanExtensions.FromSamples(1, daq.SampleRate))); Assert.That(e.Responses[dev1].Duration, Is.EqualTo(((TimeSpan)e.Duration)) .Within(TimeSpanExtensions.FromSamples(1, daq.SampleRate))); var failures0 = e.Responses[dev0].Data.Select( (t, i) => new {index = i, diff = t.QuantityInBaseUnits - stimData[i].QuantityInBaseUnits}) .Where(dif => Math.Abs(dif.diff) > (decimal) MAX_VOLTAGE_DIFF); foreach (var failure in failures0.Take(10)) Console.WriteLine("{0}: {1}", failure.index, failure.diff); /* * According to Telly @ Heka, a patch cable may introduce 3-4 offset points */ Assert.That(failures0.Count(), Is.LessThanOrEqualTo(4)); prevTime = e.StartTime; } } finally { if (daq.IsHardwareReady) { daq.CloseHardware(); } } } }
public void MaxBandwidth( [Values(1000,10000,25000,50000)] decimal sampleRate, [Values(1,1,1,1)] int nEpochs, [Values(4,4,4,4)] int nOut, [Values(8,8,8,4)] int nIn ) { Converters.Clear(); HekaDAQInputStream.RegisterConverters(); HekaDAQOutputStream.RegisterConverters(); Assert.That(HekaDAQController.AvailableControllers().Count(), Is.GreaterThan(0)); foreach (var daq in HekaDAQController.AvailableControllers()) { const double epochDuration = 10; //s daq.InitHardware(); try { daq.SampleRate = new Measurement(sampleRate, "Hz"); var controller = new Controller { Clock = daq.Clock, DAQController = daq }; var outDevices = Enumerable.Range(0, nOut) .Select(i => { var dev0 = new UnitConvertingExternalDevice("Device_OUT_" + i, "Manufacturer", controller, new Measurement(0, "V")) { MeasurementConversionTarget = "V", Clock = daq.Clock, OutputSampleRate = daq.SampleRate }; dev0.BindStream((IDAQOutputStream)daq.GetStreams("ao" + i).First()); return dev0; }) .ToList(); var inDevices = Enumerable.Range(0, nIn) .Select(i => { var dev0 = new UnitConvertingExternalDevice("Device_IN_" + i, "Manufacturer", controller, new Measurement(0, "V")) { MeasurementConversionTarget = "V", Clock = daq.Clock, InputSampleRate = daq.SampleRate }; dev0.BindStream((IDAQInputStream)daq.GetStreams("ai" + i).First()); return dev0; }) .ToList(); for (int j = 0; j < nEpochs; j++) { // Setup Epoch var e = new Epoch("HekaIntegration"); var nSamples = (int)TimeSpan.FromSeconds(epochDuration).Samples(daq.SampleRate); IList<IMeasurement> stimData = Enumerable.Range(0, nSamples) .Select(i => new Measurement((decimal)(8 * Math.Sin(((double)i) / (nSamples / 10.0))), "V") as IMeasurement) .ToList(); foreach (var outDev in outDevices) { e.Stimuli[outDev] = new RenderedStimulus((string) "RenderedStimulus", (IDictionary<string, object>) new Dictionary<string, object>(), (IOutputData) new OutputData(stimData, daq.SampleRate)); e.Backgrounds[outDev] = new Background(new Measurement(0, "V"), daq.SampleRate); } foreach (var inDev in inDevices) { e.Responses[inDev] = new Response(); } //Run single epoch var fakeEpochPersistor = new FakeEpochPersistor(); controller.RunEpoch(e, fakeEpochPersistor); Assert.That((bool)e.StartTime, Is.True); Assert.That((DateTimeOffset)e.StartTime, Is.LessThanOrEqualTo(controller.Clock.Now)); Assert.That(fakeEpochPersistor.PersistedEpochs, Contains.Item(e)); } } finally { if (daq.IsHardwareReady) daq.CloseHardware(); } } }
public void LongEpochPersistence( [Values(5,60)] double epochDuration, //seconds [Values(2)] int nEpochs ) { const decimal sampleRate = 10000m; const string h5Path = "..\\..\\..\\LongEpochPersistence.h5"; if (File.Exists(h5Path)) File.Delete(h5Path); Converters.Clear(); Converters.Register("V", "V", // just an identity conversion for now, to pass Validate() (IMeasurement m) => m); HekaDAQInputStream.RegisterConverters(); HekaDAQOutputStream.RegisterConverters(); Assert.That(HekaDAQController.AvailableControllers().Count(), Is.GreaterThan(0)); using (var persistor = H5EpochPersistor.Create(h5Path)) { persistor.AddSource("source", null); } foreach (var daq in HekaDAQController.AvailableControllers()) { try { daq.InitHardware(); daq.SampleRate = new Measurement(sampleRate, "Hz"); var controller = new Controller {Clock = daq.Clock, DAQController = daq}; var dev0 = new UnitConvertingExternalDevice("Device0", "Manufacturer", controller, new Measurement(0, "V")) { MeasurementConversionTarget = "V", Clock = daq.Clock, OutputSampleRate = daq.SampleRate, InputSampleRate = daq.SampleRate }; dev0.BindStream((IDAQOutputStream) daq.GetStreams("ao0").First()); dev0.BindStream((IDAQInputStream) daq.GetStreams("ai0").First()); for (int j = 0; j < nEpochs; j++) { // Setup Epoch var e = new Epoch("HekaIntegration"); var nSamples = (int) TimeSpan.FromSeconds(epochDuration).Samples(daq.SampleRate); 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(); e.Stimuli[dev0] = new RenderedStimulus((string) "RenderedStimulus", (IDictionary<string, object>) new Dictionary<string, object>(), (IOutputData) new OutputData(stimData, daq.SampleRate)); e.Responses[dev0] = new Response(); e.Backgrounds[dev0] = new Background(new Measurement(0, "V"), daq.SampleRate); //Run single epoch using (var persistor = new H5EpochPersistor(h5Path)) { var source = persistor.Experiment.Sources.First(); persistor.BeginEpochGroup("label", source, DateTimeOffset.Now); persistor.BeginEpochBlock(e.ProtocolID, e.ProtocolParameters, DateTimeOffset.Now); controller.RunEpoch(e, persistor); persistor.EndEpochBlock(DateTimeOffset.Now); persistor.EndEpochGroup(); } Assert.That((bool) e.StartTime, Is.True); Assert.That((DateTimeOffset) e.StartTime, Is.LessThanOrEqualTo(controller.Clock.Now)); Assert.That(e.Responses[dev0].Duration, Is.EqualTo(((TimeSpan) e.Duration)) .Within(TimeSpanExtensions.FromSamples(1, daq. SampleRate))); //Assert.That(e.Responses[dev1].Duration, Is.EqualTo(((TimeSpan) e.Duration)) // .Within(TimeSpanExtensions.FromSamples(1, // daq. // SampleRate))); } } finally { if (File.Exists(h5Path)) File.Delete(h5Path); if (daq.IsHardwareReady) daq.CloseHardware(); } } }
public void PullOutputDataShouldReturnBackgroundStreamWithNoRemainingEpochs() { var daq = new SimpleDAQController(); Controller c = new NonValidatingController() { DAQController = daq }; IExternalDevice dev = new UnitConvertingExternalDevice(UNUSED_DEVICE_NAME, UNUSED_DEVICE_MANUFACTURER, c, UNUSED_BACKGROUND) { OutputSampleRate = new Measurement(1000, "Hz") }; dev.BindStream(new DAQOutputStream("out")); var srate = dev.OutputSampleRate; TimeSpan dur = TimeSpan.FromSeconds(0.5); var samples = (int)dur.Samples(srate); var e = new Epoch(""); e.Stimuli[dev] = new RenderedStimulus("RenderedStimulus", new Dictionary<string, object>(), new OutputData(Enumerable.Repeat(new Measurement(0, "V"), samples), srate)); IOutputData pull1 = null; IOutputData pull2 = null; bool pulled = false; daq.Started += (evt, args) => { // Pull out epoch data c.PullOutputData(dev, dur); pull1 = c.PullOutputData(dev, dur); pull2 = c.PullOutputData(dev, dur); pulled = true; c.RequestStop(); }; c.EnqueueEpoch(e); c.StartAsync(null); while (!pulled) { Thread.Sleep(1); } var expected = Enumerable.Repeat(dev.Background, samples).ToList(); Assert.AreEqual(expected, pull1.Data); Assert.AreEqual(expected, pull2.Data); }
public void RunEpochThrowsWhenRunningSimultaneousEpochs() { Converters.Register("V", "V", // just an identity conversion for now, to pass Validate() (IMeasurement m) => m); var c = new Controller { DAQController = new SimpleDAQController() }; c.DAQController.Clock = c.DAQController as IClock; var sampleRate = new Measurement(1, "Hz"); var e = new Epoch(UNUSED_PROTOCOL); var dev = new UnitConvertingExternalDevice("dev", "co", c, new Measurement(0, "V")) { MeasurementConversionTarget = "V", Clock = c.Clock, OutputSampleRate = sampleRate }; var outStream = new DAQOutputStream("out") { MeasurementConversionTarget = "V", Clock = c.Clock }; dev.BindStream(outStream); e.Stimuli[dev] = new DelegatedStimulus("ID1", "units", sampleRate, new Dictionary<string, object>(), (parameters, duration) => null, objects => Option<TimeSpan>.None()); bool started = false; c.Started += (evt, args) => { started = true; }; c.EnqueueEpoch(e); c.StartAsync(null); while (!started) { Thread.Sleep(1); } Assert.That(() => c.RunEpoch(e, new FakeEpochPersistor()), Throws.Exception.TypeOf<SymphonyControllerException>()); }
public void ExternalDeviceStreams() { var ed = new UnitConvertingExternalDevice("TestDevice", UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND); DAQInputStream in0 = new DAQInputStream("In-0"); DAQOutputStream out0 = new DAQOutputStream("Out-0"); ed.BindStream(in0).BindStream(out0); Assert.IsTrue(ed.Streams.ContainsKey(in0.Name)); Assert.IsTrue(in0.Devices.Contains(ed)); Assert.IsTrue(ed.Streams.ContainsKey(out0.Name)); Assert.IsTrue(out0.Device == ed); ed.UnbindStream("In-0"); Assert.IsFalse(ed.Streams.ContainsKey(in0.Name)); Assert.IsFalse(in0.Devices.Contains(ed)); Assert.IsTrue(ed.Streams.ContainsKey(out0.Name)); Assert.IsTrue(out0.Device == ed); ed.UnbindStream("Out-0"); Assert.IsFalse(ed.Streams.ContainsKey(in0.Name)); Assert.IsFalse(in0.Devices.Contains(ed)); Assert.IsFalse(ed.Streams.ContainsKey(out0.Name)); Assert.IsFalse(out0.Device == ed); }
public void PushesDataToEpoch() { const string UNUSED_NAME = "UNUSED"; var daq = new SimpleDAQController(); var c = new NonValidatingController { DAQController = daq }; var dev = new UnitConvertingExternalDevice(UNUSED_NAME, UNUSED_DEVICE_MANUFACTURER, c, UNUSED_BACKGROUND); var outStream = new DAQOutputStream("out"); var inStream = new DAQInputStream("in"); dev.BindStream(outStream).BindStream(inStream); var srate = new Measurement(100, "Hz"); var samples = Enumerable.Range(0, 100).Select(i => new Measurement(1, "V")).ToList(); var e = new Epoch("PushesDataToEpoch"); e.Responses[dev] = new Response(); e.Stimuli[dev] = new RenderedStimulus((string) "ID1", (IDictionary<string, object>) new Dictionary<string, object>(), (IOutputData) new OutputData(samples, srate, false)); var data = new InputData(samples, srate, DateTimeOffset.Now).DataWithStreamConfiguration(inStream, new Dictionary<string, object>()); bool pushed = false; daq.Started += (evt, args) => { c.PushInputData(dev, data); pushed = true; c.RequestStop(); }; c.EnqueueEpoch(e); c.StartAsync(null); while (!pushed) { Thread.Sleep(1); } Assert.That(e.Responses[dev].Data, Is.EqualTo(data.Data)); Assert.That(e.Responses[dev].InputTime, Is.EqualTo(data.InputTime)); Assert.That(e.Responses[dev].DataConfigurationSpans.First().Nodes.First(), Is.EqualTo(data.NodeConfigurationWithName(inStream.Name))); }
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 ShouldTruncateResponseAtEpochBoundary() { Converters.Register("V", "V", (IMeasurement m) => m); var daq = new SimpleDAQController(); var c = new NonValidatingController { DAQController = daq }; var dev = new UnitConvertingExternalDevice("dev", UNUSED_DEVICE_MANUFACTURER, c, UNUSED_BACKGROUND); var outStream = new DAQOutputStream("out"); var inStream = new DAQInputStream("in"); dev.BindStream(outStream).BindStream(inStream); var sampleRate = new Measurement(1, "Hz"); var samples = new List<IMeasurement> { new Measurement(1, "V"), new Measurement(2, "V"), new Measurement(3, "V") }; var data = new OutputData(samples, sampleRate, true); var e = new Epoch(UNUSED_PROTOCOL); e.Stimuli[dev] = new RenderedStimulus((string) "ID1", (IDictionary<string, object>) new Dictionary<string, object>(), (IOutputData) data); e.Responses[dev] = new Response(); bool pushed = false; daq.Started += (evt, args) => { c.PullOutputData(dev, data.Duration); c.PushInputData(dev, new InputData(samples.Concat(samples).ToList(), sampleRate, DateTimeOffset.Now) .DataWithStreamConfiguration(streamFake, new Dictionary<string, object>()) .DataWithExternalDeviceConfiguration(devFake, new Dictionary<string, object>())); pushed = true; c.RequestStop(); }; c.EnqueueEpoch(e); c.StartAsync(null); while (!pushed) { Thread.Sleep(1); } Assert.That(((TimeSpan)e.Responses[dev].Duration), Is.EqualTo((TimeSpan)e.Duration)); }
public void ShouldSupplyEpochBackgroundForExternalDevicesWithoutStimuli() { Converters.Register("V", "V", (IMeasurement m) => m); int baseSamples = 1000; var daq = new SimpleDAQController(); var c = new NonValidatingController { DAQController = daq }; var dev1 = new UnitConvertingExternalDevice("dev1", "co", c, new Measurement(0, "V")) { OutputSampleRate = new Measurement(baseSamples, "Hz") }; var dev2 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V")) { OutputSampleRate = new Measurement(baseSamples, "Hz") }; dev1.BindStream(new DAQOutputStream("out1")); dev2.BindStream(new DAQOutputStream("out2")); 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.Backgrounds[dev2] = new Background(backgroundMeasurement, sampleRate); IOutputData out1 = null; IOutputData out2 = null; bool pulled = false; daq.Started += (evt, args) => { out1 = c.PullOutputData(dev1, e.Duration); out2 = c.PullOutputData(dev2, e.Duration); pulled = true; c.RequestStop(); }; c.EnqueueEpoch(e); c.StartAsync(null); while (!pulled) { Thread.Sleep(1); } Assert.NotNull(out1); Assert.NotNull(out2); Assert.AreEqual((TimeSpan)e.Duration, out2.Duration); Assert.AreEqual(backgroundMeasurement, out2.Data.First()); }
public void ShouldPersistCompletedEpochs() { Converters.Register("V", "V", (IMeasurement m) => m); var c = new Controller(); bool evt = false; c.DAQController = new TestDAQController(); c.Clock = c.DAQController as IClock; var persistor = new FakeEpochPersistor(); c.SavedEpoch += (co, args) => { evt = true; }; var srate = new Measurement(10, "Hz"); var dev = new UnitConvertingExternalDevice(UNUSED_DEVICE_NAME, UNUSED_DEVICE_MANUFACTURER, c, UNUSED_BACKGROUND) { MeasurementConversionTarget = "V", Clock = c.Clock, OutputSampleRate = srate, InputSampleRate = srate }; var outStream = new DAQOutputStream("outStream") { MeasurementConversionTarget = "V", Clock = c.Clock }; var inStream = new DAQInputStream("inStream") { MeasurementConversionTarget = "V", Clock = c.Clock }; (c.DAQController as IMutableDAQController).AddStream(outStream); (c.DAQController as IMutableDAQController).AddStream(inStream); 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.Backgrounds[dev] = new Background(new Measurement(0, "V"), srate); ((TestDAQController)c.DAQController).AddStreamMapping(outStream, inStream); c.RunEpoch(e, persistor); Assert.That(evt, Is.True.After(10*1000,100)); Assert.That(persistor.PersistedEpochs, Has.Member(e)); }
public void SealLeak( [Values(10000, 20000, 50000)] double sampleRate ) { Converters.Clear(); Converters.Register("V", "V", // just an identity conversion for now, to pass Validate() (IMeasurement m) => m); HekaDAQInputStream.RegisterConverters(); HekaDAQOutputStream.RegisterConverters(); Assert.That(HekaDAQController.AvailableControllers().Count(), Is.GreaterThan(0)); foreach (var daq in HekaDAQController.AvailableControllers()) { const double epochDuration = 10; //s //Configure DAQ daq.InitHardware(); try { daq.SampleRate = new Measurement((decimal)sampleRate, "Hz"); var controller = new Controller(); controller.Clock = daq.Clock; controller.DAQController = daq; const decimal expectedBackgroundVoltage = 3.2m; var expectedBackground = new Measurement(expectedBackgroundVoltage, "V"); var dev0 = new UnitConvertingExternalDevice("Device0", "Manufacturer", controller, expectedBackground) { MeasurementConversionTarget = "V", Clock = daq.Clock, OutputSampleRate = daq.SampleRate, InputSampleRate = daq.SampleRate }; dev0.BindStream(daq.GetStreams("ao0").First() as IDAQOutputStream); dev0.BindStream(daq.GetStreams("ai0").First() as IDAQInputStream); controller.DiscardedEpoch += (c, args) => Console.WriteLine("Discarded epoch: " + args.Epoch); // Setup Epoch var e = new Epoch("HekaIntegration"); HekaDAQController cDAQ = daq; var stim = new DelegatedStimulus("TEST_ID", "V", cDAQ.SampleRate, new Dictionary<string, object>(), (parameters, duration) => DataForDuration(duration, cDAQ.SampleRate), parameters => Option<TimeSpan>.None() ); e.Stimuli[dev0] = stim; e.Backgrounds[dev0] = new Background(expectedBackground, daq.SampleRate); //Run single epoch var fakeEpochPersistor = new FakeEpochPersistor(); new TaskFactory().StartNew(() => { Thread.Sleep(TimeSpan.FromSeconds(epochDuration)); controller.RequestStop(); }, TaskCreationOptions.LongRunning ); controller.RunEpoch(e, fakeEpochPersistor); } finally { if (daq.IsHardwareReady) daq.CloseHardware(); } } }
public void ShouldSetStreamBackgroundOnStop( [Values(10000, 20000)] double sampleRate ) { Converters.Clear(); Converters.Register("V", "V", // just an identity conversion for now, to pass Validate() (IMeasurement m) => m); HekaDAQInputStream.RegisterConverters(); HekaDAQOutputStream.RegisterConverters(); Assert.That(HekaDAQController.AvailableControllers().Count(), Is.GreaterThan(0)); foreach (var daq in HekaDAQController.AvailableControllers()) { const double epochDuration = 1; //s //Configure DAQ daq.InitHardware(); try { daq.SampleRate = new Measurement((decimal)sampleRate, "Hz"); var controller = new Controller(); controller.Clock = daq.Clock; controller.DAQController = daq; const decimal expectedBackgroundVoltage = -3.2m; var expectedBackground = new Measurement(expectedBackgroundVoltage, "V"); var dev0 = new UnitConvertingExternalDevice("Device0", "Manufacturer", controller, expectedBackground) { MeasurementConversionTarget = "V", OutputSampleRate = daq.SampleRate, InputSampleRate = daq.SampleRate }; dev0.BindStream(daq.GetStreams("ao0").First() as IDAQOutputStream); dev0.BindStream(daq.GetStreams("ai0").First() as IDAQInputStream); dev0.Clock = daq.Clock; controller.DiscardedEpoch += (c, args) => Console.WriteLine("Discarded epoch: " + args.Epoch); // Setup Epoch var e = new Epoch("HekaIntegration"); var nSamples = (int)TimeSpanExtensions.Samples(TimeSpan.FromSeconds(epochDuration), daq.SampleRate); 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(); var stim = new RenderedStimulus((string) "RenderedStimulus", (IDictionary<string, object>) new Dictionary<string, object>(), (IOutputData) new OutputData(stimData, daq.SampleRate, false)); e.Stimuli[dev0] = stim; e.Responses[dev0] = new Response(); e.Backgrounds[dev0] = new Background(expectedBackground, daq.SampleRate); //Run single epoch var fakeEpochPersistor = new FakeEpochPersistor(); controller.RunEpoch(e, fakeEpochPersistor); Thread.Sleep(TimeSpan.FromMilliseconds(100)); //allow DAC to settle var actual = ((HekaDAQController)controller.DAQController).ReadStreamAsync( daq.GetStreams("ai0").First() as IDAQInputStream); //Should be within +/- 0.025 volts Assert.That(actual.Data.First().QuantityInBaseUnits, Is.InRange(expectedBackground.QuantityInBaseUnits - (decimal)0.025, expectedBackground.QuantityInBaseUnits + (decimal)0.025)); } finally { if (daq.IsHardwareReady) daq.CloseHardware(); } } }
public void PullsOutputData() { const int srate = 1000; var daq = new SimpleDAQController(); var c = new NonValidatingController { DAQController = daq }; var dev = new UnitConvertingExternalDevice(UNUSED_DEVICE_NAME, UNUSED_DEVICE_MANUFACTURER, c, UNUSED_BACKGROUND) { OutputSampleRate = new Measurement(srate, "Hz") }; dev.BindStream(new DAQOutputStream("out")); 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); TimeSpan d1 = TimeSpan.FromSeconds(0.75); IOutputData pull1 = null; IOutputData pull2 = null; IOutputData pull3 = null; bool pulled = false; daq.Started += (evt, args) => { pull1 = c.PullOutputData(dev, d1); pull2 = c.PullOutputData(dev, d1); pull3 = c.PullOutputData(dev, d1); pulled = true; c.RequestStop(); }; c.EnqueueEpoch(e); c.StartAsync(null); while (!pulled) { Thread.Sleep(1); } 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); Assert.AreEqual(data.Skip(2 * samples) .Take(samples) .Concat(Enumerable.Range(0, srate - samples).Select(i => dev.Background)) .ToList(), pull3.Data); }
public void CreatePipeline() { // Based on the "Minimal Rig.pdf" in the docs folder Converters.Clear(); // We need an IClock IClock clock = new FakeClock(); // We need a controller ... Controller con = new Controller(); Converters.Register("units", "units", // just an identity conversion for now, to pass Validate() (IMeasurement m) => m); Converters.Register("V", "units", // just an identity conversion for now, to pass Validate() (IMeasurement m) => m); con.Clock = clock; // Three ExternalDevices CoalescingDevice amp = new CoalescingDevice("Amp", UNUSED_DEVICE_MANUFACTURER, con, UNUSED_BACKGROUND) { MeasurementConversionTarget = "units" }; var LED = new UnitConvertingExternalDevice("LED", UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND) { MeasurementConversionTarget = "units" }; var temp = new UnitConvertingExternalDevice("Temp", UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND) { MeasurementConversionTarget = "units" }; amp.Clock = clock; LED.Clock = clock; temp.Clock = clock; con.AddDevice(LED).AddDevice(temp); // There should be no difference whether we use the // ExternalDevice constructor to wire up the Controller // to the ExternalDevice, or the explicit Add() call Assert.IsNotNull(amp.Controller); Assert.IsNotNull(LED.Controller); Assert.IsNotNull(temp.Controller); Assert.IsTrue(amp.Controller == con); Assert.IsTrue(LED.Controller == con); Assert.IsTrue(temp.Controller == con); // Five DAQStreams DAQInputStream in0 = new DAQInputStream("In-0"); in0.Clock = clock; DAQInputStream in1 = new DAQInputStream("In-1"); in1.Clock = clock; DAQInputStream in2 = new DAQInputStream("In-2"); in2.Clock = clock; DAQOutputStream out0 = new DAQOutputStream("Out-0"); out0.Clock = clock; DAQOutputStream out1 = new DAQOutputStream("Out-1"); out1.Clock = clock; in0.MeasurementConversionTarget = "units"; in1.MeasurementConversionTarget = "units"; in2.MeasurementConversionTarget = "units"; out0.MeasurementConversionTarget = "units"; out1.MeasurementConversionTarget = "units"; //amp.Coalesce = CoalescingDevice.OneItemCoalesce; amp.Configuration["CoalesceProc"] = "Symphony.Core.CoalescingDevice.OneItemCoalesce"; LED.BindStream(out0); amp.BindStream(out1).BindStream(in0).BindStream(in1); amp.Connect(in0, in1); temp.BindStream(in2); Assert.IsTrue(LED.Streams.Count == 1); Assert.IsTrue(amp.Streams.Count == 3); Assert.IsTrue(temp.Streams.Count == 1); Assert.IsTrue(in0.Devices.Contains(amp)); Assert.IsTrue(in1.Devices.Contains(amp)); Assert.IsTrue(in2.Devices.Contains(temp)); Assert.IsTrue(out0.Device == LED); Assert.IsTrue(out1.Device == amp); // One DAQController IDAQController dc = new SimpleDAQController(new IDAQStream[] { in0, in1, in2, out0, out1 }); con.DAQController = dc; // DAQController-to-streams Assert.IsTrue(dc.InputStreams.Contains(in0)); Assert.IsTrue(dc.InputStreams.Contains(in1)); Assert.IsTrue(dc.InputStreams.Contains(in2)); Assert.IsTrue(dc.OutputStreams.Contains(out0)); Assert.IsTrue(dc.OutputStreams.Contains(out0)); // Validate and report the validation results Maybe<string> conVal = con.Validate(); Assert.IsTrue(conVal, conVal.Item2); Assert.IsTrue(amp.Coalesce == CoalescingDevice.OneItemCoalesce); }
public void RunEpochShouldDiscardEpochWhenRequestStopCalled() { Converters.Register("V", "V", // just an identity conversion for now, to pass Validate() (IMeasurement m) => m); var c = new Controller { DAQController = new SimpleDAQController2() }; c.DAQController.Clock = c.DAQController as IClock; var sampleRate = new Measurement(1, "Hz"); var e = new Epoch(UNUSED_PROTOCOL); var dev1 = new UnitConvertingExternalDevice("dev1", "co", c, new Measurement(0, "V")) { MeasurementConversionTarget = "V", Clock = c.Clock, OutputSampleRate = sampleRate }; var outStream = new DAQOutputStream("out") { MeasurementConversionTarget = "V", Clock = c.Clock }; dev1.BindStream(outStream); e.Stimuli[dev1] = new DelegatedStimulus("ID1", "units", sampleRate, new Dictionary<string, object>(), (parameters, duration) => new OutputData(new List<IMeasurement>(), sampleRate, false), objects => Option<TimeSpan>.None()); bool epochDiscarded = false; c.DiscardedEpoch += (sender, args) => { epochDiscarded = true; }; c.DAQController.ProcessIteration += (o, eventArgs) => { Console.WriteLine("Process iteration"); c.RequestStop(); }; c.RunEpoch(e, new FakeEpochPersistor()); Assert.True(epochDiscarded); }
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 CreatePipeline() { // Based on the "Minimal Rig.pdf" in the docs folder Converters.Clear(); // We need an IClock IClock clock = new FakeClock(); // We need a controller ... Controller con = new Controller(); Converters.Register("units", "units", // just an identity conversion for now, to pass Validate() (IMeasurement m) => m); Converters.Register("V", "units", // just an identity conversion for now, to pass Validate() (IMeasurement m) => m); con.Clock = clock; // Three ExternalDevices CoalescingDevice amp = new CoalescingDevice("Amp", UNUSED_DEVICE_MANUFACTURER, con, UNUSED_BACKGROUND) { MeasurementConversionTarget = "units" }; var LED = new UnitConvertingExternalDevice("LED", UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND) { MeasurementConversionTarget = "units" }; var temp = new UnitConvertingExternalDevice("Temp", UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND) { MeasurementConversionTarget = "units" }; amp.Clock = clock; LED.Clock = clock; temp.Clock = clock; con.AddDevice(LED).AddDevice(temp); // There should be no difference whether we use the // ExternalDevice constructor to wire up the Controller // to the ExternalDevice, or the explicit Add() call Assert.IsNotNull(amp.Controller); Assert.IsNotNull(LED.Controller); Assert.IsNotNull(temp.Controller); Assert.IsTrue(amp.Controller == con); Assert.IsTrue(LED.Controller == con); Assert.IsTrue(temp.Controller == con); // Five DAQStreams DAQInputStream in0 = new DAQInputStream("In-0"); in0.Clock = clock; DAQInputStream in1 = new DAQInputStream("In-1"); in1.Clock = clock; DAQInputStream in2 = new DAQInputStream("In-2"); in2.Clock = clock; DAQOutputStream out0 = new DAQOutputStream("Out-0"); out0.Clock = clock; DAQOutputStream out1 = new DAQOutputStream("Out-1"); out1.Clock = clock; in0.MeasurementConversionTarget = "units"; in1.MeasurementConversionTarget = "units"; in2.MeasurementConversionTarget = "units"; out0.MeasurementConversionTarget = "units"; out1.MeasurementConversionTarget = "units"; //amp.Coalesce = CoalescingDevice.OneItemCoalesce; amp.Configuration["CoalesceProc"] = "Symphony.Core.CoalescingDevice.OneItemCoalesce"; LED.BindStream(out0); amp.BindStream(out1).BindStream(in0).BindStream(in1); amp.Connect(in0, in1); temp.BindStream(in2); Assert.IsTrue(LED.Streams.Count == 1); Assert.IsTrue(amp.Streams.Count == 3); Assert.IsTrue(temp.Streams.Count == 1); Assert.IsTrue(in0.Devices.Contains(amp)); Assert.IsTrue(in1.Devices.Contains(amp)); Assert.IsTrue(in2.Devices.Contains(temp)); Assert.IsTrue(out0.Device == LED); Assert.IsTrue(out1.Device == amp); // One DAQController IDAQController dc = new SimpleDAQController(new IDAQStream[] { in0, in1, in2, out0, out1 }); con.DAQController = dc; // DAQController-to-streams Assert.IsTrue(dc.InputStreams.Contains(in0)); Assert.IsTrue(dc.InputStreams.Contains(in1)); Assert.IsTrue(dc.InputStreams.Contains(in2)); Assert.IsTrue(dc.OutputStreams.Contains(out0)); Assert.IsTrue(dc.OutputStreams.Contains(out0)); // Validate and report the validation results Maybe <string> conVal = con.Validate(); Assert.IsTrue(conVal, conVal.Item2); Assert.IsTrue(amp.Coalesce == CoalescingDevice.OneItemCoalesce); }
public void ShouldRaiseExceptionIfPullingLessThanOneSample() { var e = new UnitConvertingExternalDevice(UNUSED_NAME, null, new Measurement(0, "V")); var stream = new DAQOutputStream(UNUSED_NAME); e.BindStream(stream); stream.SampleRate = new Measurement(1, "Hz"); Assert.Throws<ExternalDeviceException>(() => e.PullOutputData(stream, TimeSpan.FromMilliseconds(0.1))); }
private static Controller SetupController(double sampleRate, out Epoch e, out IExternalDevice dev0, out RenderedStimulus stim1, out IExternalDevice dev1, out RenderedStimulus stim2, out IList<IMeasurement> stimData, int nChannels) { Converters.Clear(); Converters.Register("V", "V", // just an identity conversion for now, to pass Validate() (IMeasurement m) => m); // use an incrementing clock so timestamps are predictable var incrementingClock = new IncrementingClock(); var daq = new SimulationDAQController { Clock = incrementingClock }; var out0 = new DAQOutputStream("Out0") { MeasurementConversionTarget = "V", Clock = daq.Clock, SampleRate = new Measurement((decimal)sampleRate, "Hz") }; var out1 = new DAQOutputStream("Out1") { MeasurementConversionTarget = "V", Clock = daq.Clock, SampleRate = new Measurement((decimal)sampleRate, "Hz") }; var in0 = new DAQInputStream("In0") { MeasurementConversionTarget = "V", Clock = daq.Clock, SampleRate = new Measurement((decimal) sampleRate, "Hz") }; var in1 = new DAQInputStream("In1") { MeasurementConversionTarget = "V", Clock = daq.Clock, SampleRate = new Measurement((decimal)sampleRate, "Hz") }; daq.AddStream(out0); daq.AddStream(out1); daq.AddStream(in0); daq.AddStream(in1); var controller = new Controller(daq, daq.Clock); var streamNameMap = new Dictionary<string, string>(); streamNameMap["Out0"] = "In0"; if (nChannels > 1) streamNameMap["Out1"] = "In1"; foreach (var stream in daq.Streams) { stream.SampleRate = new Measurement((decimal) sampleRate, "Hz"); } daq.SimulationRunner += (output, timestep) => { var input = new ConcurrentDictionary<IDAQInputStream, IInputData>(); Parallel.ForEach(output, (kv) => { var outData = kv.Value; var outStream = kv.Key; var inStream = daq.InputStreams.Where((s) => s.Name == streamNameMap[outStream.Name]).First(); var data = outData.DataWithUnits("V").Data; var inData = new InputData(data, outData.SampleRate, incrementingClock.Now) .DataWithNodeConfiguration("SimulationController",daq.Configuration); input[inStream] = inData; } ); return input; }; var protocolParams = new Dictionary<string, object>(1); protocolParams["key1"] = "value1"; e = new Epoch("LowGainSimulation", protocolParams); dev0 = new UnitConvertingExternalDevice("Device0", "Manufacturer", controller, new Measurement(0, "V")) { MeasurementConversionTarget = "V", Clock = daq.Clock, InputSampleRate = new Measurement((decimal)sampleRate, "Hz"), OutputSampleRate = new Measurement((decimal)sampleRate, "Hz") }; dev0.BindStream(out0); dev0.BindStream(in0); dev1 = new UnitConvertingExternalDevice("Device1", "Manufacturer", controller, new Measurement(0, "V")) { MeasurementConversionTarget = "V", Clock = daq.Clock, InputSampleRate = new Measurement((decimal)sampleRate, "Hz"), OutputSampleRate = new Measurement((decimal)sampleRate, "Hz") }; dev1.BindStream(out1); dev1.BindStream(in1); if (nChannels == 1) { dev1.UnbindStream(dev1.Streams.Values.First().Name); } stimData = Enumerable.Range(0, (int)(10 * sampleRate)) .Select(i => new Measurement(i, -3, "V") as IMeasurement) .ToList(); var srate = new Measurement((decimal) sampleRate, "Hz"); stim1 = new RenderedStimulus((string) "RenderedStimulus", (IDictionary<string, object>) new Dictionary<string, object>(), (IOutputData) new OutputData(stimData, srate, false)); stim2 = new RenderedStimulus((string) "RenderedStimulus", (IDictionary<string, object>) new Dictionary<string, object>(), (IOutputData) new OutputData(stimData, srate, false)); e.Stimuli[dev0] = stim1; if (nChannels > 1) e.Stimuli[dev1] = stim2; e.Responses[dev0] = new Response(); if (nChannels > 1) e.Responses[dev1] = new Response(); e.Backgrounds[dev0] = new Background(new Measurement(0, "V"), srate); e.Backgrounds[dev1] = new Background(new Measurement(0, "V"), srate); return controller; }