public void NextEpochShouldFireNextEpochEvent()
        {
            var c = new Controller();

            c.Clock = new FakeClock();

            var e    = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            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);

            e.Stimuli[dev1] = new RenderedStimulus((string)"ID1",
                                                   (IDictionary <string, object>) new Dictionary <string, object>(),
                                                   (IOutputData)data);
            e.Responses[dev1] = new Response();

            c.EnqueueEpoch(e);

            bool evt = false;

            c.NextEpochRequested += (sender, args) => evt = true;

            c.NextEpoch();

            Assert.True(evt);
        }
Exemple #2
0
        public void IsIndefiniteIfAnyStimulusIsIndefinite()
        {
            Epoch e    = new Epoch("");
            var   dev  = new UnitConvertingExternalDevice("name", "co", new Measurement(1.0m, "units"));
            var   dev2 = new UnitConvertingExternalDevice("name2", "co", new Measurement(1.0m, "units"));

            Assert.That(e.IsIndefinite, Is.False);

            e.Stimuli[dev2] = new DelegatedStimulus("stimID", "units",
                                                    new Dictionary <string, object>(),
                                                    (p, b) => null,
                                                    (p) => Option <TimeSpan> .Some(TimeSpan.FromMilliseconds(100)));

            Assert.That(e.IsIndefinite, Is.False);

            e.Stimuli[dev] = new DelegatedStimulus("stimID", "units",
                                                   new Dictionary <string, object>(),
                                                   (p, b) => null,
                                                   (p) => Option <TimeSpan> .None());

            Assert.That(e.IsIndefinite, Is.True);

            e.Stimuli.Clear();

            Assert.That(e.IsIndefinite, Is.False);
        }
        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);
        }
Exemple #4
0
        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 RunEpochThrowsGivenEpochWithInconsistentStimulusDurations()
        {
            var c = new Controller();

            var e    = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev1", "co", c, new Measurement(0, "V"));
            var dev2 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            var sampleRate = new Measurement(1, "Hz");

            e.Stimuli[dev1] = new RenderedStimulus((string)"ID1",
                                                   (IDictionary <string, object>) new Dictionary <string, object>(),
                                                   (IOutputData) new OutputData(new List <IMeasurement> {
                new Measurement(1, "V")
            },
                                                                                sampleRate, true));

            e.Stimuli[dev2] = new RenderedStimulus((string)"ID2",
                                                   (IDictionary <string, object>) new Dictionary <string, object>(),
                                                   (IOutputData) new OutputData(new List <IMeasurement> {
                new Measurement(1, "V"), new Measurement(1, "V")
            },
                                                                                sampleRate, true));

            Assert.That(() => c.RunEpoch(e, new FakeEpochPersistor()), Throws.Exception.TypeOf <ArgumentException>());

            e.Stimuli[dev2] = new DelegatedStimulus("ID2", "V",
                                                    new Dictionary <string, object>(),
                                                    (x, y) => null,
                                                    (p) => Option <TimeSpan> .None());

            Assert.That(() => c.RunEpoch(e, new FakeEpochPersistor()), Throws.Exception.TypeOf <ArgumentException>());
        }
        public void DoesNotPushStimulusConfigurationSpansToCompletedEpochs()
        {
            const string UNUSED_NAME = "UNUSED";

            var c   = new SingleEpochController();
            var dev = new UnitConvertingExternalDevice(UNUSED_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND);

            var outputTime    = DateTimeOffset.Now;
            var configuration = new List <IPipelineNodeConfiguration>();
            var config        = new Dictionary <string, object>();

            config["key"] = "value";

            configuration.Add(new PipelineNodeConfiguration(UNUSED_NAME, config));

            var epochMock = new Mock <Epoch>("test-epoch");

            epochMock.Setup(epoch => epoch.DidOutputData(dev, outputTime, TimeSpan.FromSeconds(0.1), configuration));
            epochMock.Setup(epoch => epoch.IsComplete).Returns(true);


            c.SetCurrentEpoch(epochMock.Object);


            c.DidOutputData(dev, outputTime, TimeSpan.FromSeconds(0.1), configuration);

            epochMock.Verify(epoch => epoch.DidOutputData(dev, outputTime, TimeSpan.FromSeconds(0.1), configuration), Times.AtMost(0));
        }
        public void ShouldTruncateResponseAtEpochBoundary()
        {
            var c = new Controller();

            var e    = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            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);

            e.Stimuli[dev1] = new RenderedStimulus((string)"ID1",
                                                   (IDictionary <string, object>) new Dictionary <string, object>(),
                                                   (IOutputData)data);
            e.Responses[dev1] = new Response();

            c.EnqueueEpoch(e);
            c.NextEpoch();
            c.PushInputData(dev1, new InputData(samples.Concat(samples).ToList(),
                                                sampleRate,
                                                DateTimeOffset.Now)
                            .DataWithStreamConfiguration(streamFake, new Dictionary <string, object>())
                            .DataWithExternalDeviceConfiguration(devFake, new Dictionary <string, object>()));

            Assert.That(((TimeSpan)e.Responses[dev1].Duration), Is.EqualTo((TimeSpan)e.Duration));
        }
        public void IsIndefiniteIfAnyStimulusIsIndefinite()
        {
            Epoch e = new Epoch("");
            var dev = new UnitConvertingExternalDevice("name", "co", new Measurement(1.0m, "units"));
            var dev2 = new UnitConvertingExternalDevice("name2", "co", new Measurement(1.0m, "units"));

            Assert.That(e.IsIndefinite, Is.False);

            e.Stimuli[dev2] = new DelegatedStimulus("stimID", "units", new Measurement(1000, "Hz"),
                                                   new Dictionary<string, object>(),
                                                   (p, b) => null,
                                                   (p) => Option<TimeSpan>.Some(TimeSpan.FromMilliseconds(100)));

            Assert.That(e.IsIndefinite, Is.False);

            e.Stimuli[dev] = new DelegatedStimulus("stimID", "units", new Measurement(1000, "Hz"),
                                                   new Dictionary<string, object>(),
                                                   (p, b) => null,
                                                   (p) => Option<TimeSpan>.None());

            Assert.That(e.IsIndefinite, Is.True);

            e.Stimuli.Clear();

            Assert.That(e.IsIndefinite, Is.False);
        }
        public void NexEpochShouldDequeueEpoch()
        {
            var c = new Controller();

            var e    = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            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);

            e.Stimuli[dev1] = new RenderedStimulus((string)"ID1",
                                                   (IDictionary <string, object>) new Dictionary <string, object>(),
                                                   (IOutputData)data);
            e.Responses[dev1] = new Response();

            c.EnqueueEpoch(e);

            Assert.That(c.CurrentEpoch, Is.Null);

            c.NextEpoch();

            Assert.That(c.CurrentEpoch, Is.EqualTo(e));
        }
        public void NextEpochThrowsIfCannotDequeue()
        {
            var c = new Controller();

            var e    = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            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);

            e.Stimuli[dev1] = new RenderedStimulus((string)"ID1",
                                                   (IDictionary <string, object>) new Dictionary <string, object>(),
                                                   (IOutputData)data);
            e.Responses[dev1] = new Response();

            c.EnqueueEpoch(e);

            c.NextEpoch();

            Assert.Throws <SymphonyControllerException>(() => c.NextEpoch());
        }
        public void PushesDataToEpoch()
        {
            const string UNUSED_NAME = "UNUSED";

            var c   = new SingleEpochController();
            var dev = new UnitConvertingExternalDevice(UNUSED_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND);

            c.AddDevice(dev);

            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));

            c.SetCurrentEpoch(e);

            var streamFake = new DAQInputStream("StreamFake");

            var data = new InputData(samples, srate, DateTimeOffset.Now)
                       .DataWithStreamConfiguration(streamFake, new Dictionary <string, object>());

            c.PushInputData(dev, data);

            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(streamFake.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 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 EmptyNameShouldFailValidation()
        {
            var e = new UnitConvertingExternalDevice("", UNUSED_NAME, new Measurement(0, "V"));
            Assert.That((bool)e.Validate(), Is.False);

            e = new UnitConvertingExternalDevice(null, UNUSED_NAME, new Measurement(0, "V"));
            Assert.That((bool)e.Validate(), Is.False);
        }
        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));
            }
        }
Exemple #16
0
        public void EmptyManufacturerShouldFailValidation()
        {
            var e = new UnitConvertingExternalDevice(UNUSED_NAME, "", new Measurement(0, "V"));

            Assert.That((bool)e.Validate(), Is.False);

            e = new UnitConvertingExternalDevice(UNUSED_NAME, null, new Measurement(0, "V"));
            Assert.That((bool)e.Validate(), Is.False);
        }
        public void PreventsDuplicateExternalDeviceNames()
        {
            Controller c = new Controller();

            const string UNUSED_NAME = "UNUSED";
            var          dev1        = new UnitConvertingExternalDevice(UNUSED_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND);
            var          dev2        = new UnitConvertingExternalDevice(UNUSED_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND);

            c.AddDevice(dev1).AddDevice(dev2);
        }
Exemple #18
0
        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 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 GetDeivceReturnsDevice()
        {
            Controller c = new Controller();

            const string DEVICE_NAME = "DEVICE";
            var          dev1        = new UnitConvertingExternalDevice(DEVICE_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND);

            c.AddDevice(dev1);

            Assert.AreEqual(dev1, c.GetDevice(DEVICE_NAME));
        }
        public void BackgroundProxiesExternalDevice()
        {
            var background = new Measurement(1.3m, "units");
            var dev = new UnitConvertingExternalDevice(UNUSED_NAME, UNUSED_DEVICE_MANUFACTURER, background)
                          {
                              MeasurementConversionTarget = "units"
                          };

            var stream = new DAQOutputStream(UNUSED_NAME);
            stream.Device = dev;

            Assert.AreEqual(background.QuantityInBaseUnit, stream.Background.QuantityInBaseUnit);
        }
        public void ShouldAllowBackgroundChanagesAfterConstruction()
        {
            const string units = "xyz";

            var device = new UnitConvertingExternalDevice("dev", "manufacturer", new Measurement(0, units)) { MeasurementConversionTarget = units };

            var expected = new Measurement(123, units);

            device.Background = expected;

            Assert.That(device.Background, Is.EqualTo(expected));
            Assert.That(device.OutputBackground, Is.EqualTo(expected));
        }
        public void BackgroundProxiesExternalDevice()
        {
            var background = new Measurement(1.3m, "units");
            var dev        = new UnitConvertingExternalDevice(UNUSED_NAME, UNUSED_DEVICE_MANUFACTURER, background)
            {
                MeasurementConversionTarget = "units"
            };

            var stream = new DAQOutputStream(UNUSED_NAME);

            stream.Device = dev;

            Assert.AreEqual(background.QuantityInBaseUnit, stream.Background.QuantityInBaseUnit);
        }
Exemple #24
0
        public void DurationsSumUpCorrectly()
        {
            Epoch e = new Epoch("Protocol");

            var ed = new UnitConvertingExternalDevice("TEST-DEVICE", "DEVICE-CO", new Measurement(0, "V"));

            IMeasurement UNUSED_SRATE = new Measurement(1000, "Hz");

            e.Stimuli[ed] = new RenderedStimulus((string)"RenderedStimulus", (IDictionary <string, object>) new Dictionary <string, object>(),
                                                 (IOutputData) new OutputData(new Measurement[] {
                new Measurement(0, "units"),
                new Measurement(1, "units")
            }.ToList(), UNUSED_SRATE, false));

            // More to do here (later)
        }
        public void DurationsSumUpCorrectly()
        {
            Epoch e = new Epoch("Protocol");

            var ed = new UnitConvertingExternalDevice("TEST-DEVICE", "DEVICE-CO", new Measurement(0, "V"));

            IMeasurement UNUSED_SRATE = new Measurement(1000, "Hz");

            e.Stimuli[ed] = new RenderedStimulus((string) "RenderedStimulus", (IDictionary<string, object>) new Dictionary<string, object>(),
                 (IOutputData) new OutputData(new Measurement[] {
                                                                    new Measurement(0, "units"),
                                                                    new Measurement(1, "units")
                                                                }.ToList(), UNUSED_SRATE, false));

            // More to do here (later)
        }
Exemple #26
0
        public void ShouldAllowBackgroundChanagesAfterConstruction()
        {
            const string units = "xyz";

            var device = new UnitConvertingExternalDevice("dev", "manufacturer", new Measurement(0, units))
            {
                MeasurementConversionTarget = units
            };

            var expected = new Measurement(123, units);

            device.Background = expected;

            Assert.That(device.Background, Is.EqualTo(expected));
            Assert.That(device.OutputBackground, Is.EqualTo(expected));
        }
        public void RunEpochThrowsGivenIndefiniteEpochWithResponses()
        {
            var c = new Controller();

            var e    = new Epoch(UNUSED_PROTOCOL);
            var dev2 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            var sampleRate = new Measurement(1, "Hz");

            e.Stimuli[dev2] = new DelegatedStimulus("ID2", "units",
                                                    new Dictionary <string, object>(),
                                                    (x, y) => null,
                                                    (p) => Option <TimeSpan> .None());
            e.Responses[dev2] = new Response();

            Assert.That(() => c.RunEpoch(e, new FakeEpochPersistor()), Throws.Exception.TypeOf <ArgumentException>());
        }
        public void RunEpochShouldDiscardEpochWhenCancelEpochCalled()
        {
            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 e    = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev1", "co", c, new Measurement(0, "V"))
            {
                MeasurementConversionTarget = "V",
                Clock = c.Clock
            };

            var sampleRate = new Measurement(1, "Hz");

            e.Stimuli[dev1] = new DelegatedStimulus("ID1", "units", 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.CancelEpoch();
            };

            c.RunEpoch(e, new FakeEpochPersistor());

            Assert.True(epochDiscarded);
        }
        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)));
        }
Exemple #30
0
        public void PullOutputDataShouldThrowForMissingDevice()
        {
            var e   = new Epoch(UNUSED_PROTOCOL_ID);
            var dev = new UnitConvertingExternalDevice("name", "co", new Measurement(1.0m, "units"));

            ArgumentException caught = null;

            try
            {
                e.PullOutputData(dev, TimeSpan.FromMilliseconds(100));
            }
            catch (ArgumentException ex)
            {
                caught = ex;
            }

            Assert.That(caught, Is.Not.Null);
        }
Exemple #31
0
        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));
        }
        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);
        }
        private static void OrderedFakeInputData(out IInputData d1, out IInputData d2)
        {
            Random random = new Random();
            IList <IMeasurement>         data   = (IList <IMeasurement>)Enumerable.Repeat(0, 100).Select(i => random.Next()).Select(v => new Measurement(v, "V") as IMeasurement).ToList();;//generate random data
            IMeasurement                 srate  = new Measurement(1000, "Hz");
            DateTimeOffset               time1  = DateTimeOffset.Now;
            IDictionary <string, object> config = new Dictionary <string, object>();
            var dev    = new UnitConvertingExternalDevice("DevName", "DevManufacturer", new Measurement(0, "V"));
            var stream = new DAQOutputStream("StreamName");

            d1 = new InputData(data, srate, time1)
                 .DataWithExternalDeviceConfiguration(dev, config)
                 .DataWithStreamConfiguration(stream, config);

            DateTimeOffset time2 = time1.AddSeconds((double)(data.Count / srate.Quantity));

            d2 = new InputData(data, srate, time2)
                 .DataWithExternalDeviceConfiguration(dev, config)
                 .DataWithStreamConfiguration(stream, config);
        }
Exemple #34
0
        public void PullOuputDataShouldReturnBackgroundWhenNoStimulusRegisteredForDevice()
        {
            var e   = new Epoch(UNUSED_PROTOCOL_ID);
            var dev = new UnitConvertingExternalDevice("name", "co", new Measurement(1.0m, "units"));

            var bg = new Measurement(1.1m, "units");

            e.Background[dev] = new Epoch.EpochBackground(bg, new Measurement(1000, "Hz"));

            var duration = TimeSpan.FromSeconds(1.1);
            var data     = e.PullOutputData(dev, duration);

            Assert.That(data.Duration, Is.EqualTo(duration));
            Assert.That(data.Data.All(m => m.BaseUnit == bg.BaseUnit));
            foreach (var m in data.Data)
            {
                Assert.That(m.QuantityInBaseUnit, Is.EqualTo(bg.QuantityInBaseUnit).Within(0.0001));
            }
            Assert.That(data.Data.All(m => m.QuantityInBaseUnit == bg.QuantityInBaseUnit));
        }
        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));
        }
Exemple #36
0
        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 EpochValidates()
        {
            var c = new Controller();

            var e    = new Epoch(UNUSED_PROTOCOL);
            var dev2 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            var sampleRate = new Measurement(1, "Hz");

            e.Stimuli[dev2] = new DelegatedStimulus("ID2", "units",
                                                    new Dictionary <string, object>(),
                                                    (x, y) => null,
                                                    (p) => Option <TimeSpan> .None());


            try
            {
                Assert.That(() => c.RunEpoch(e, new FakeEpochPersistor()), Throws.Nothing);
            }
            catch (Exception)
            {
                //pass
            }
        }
        public void ShouldTruncateResponseAtEpochBoundary()
        {
            var c = new Controller();

            var e = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            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);

            e.Stimuli[dev1] = new RenderedStimulus((string) "ID1",
                                                   (IDictionary<string, object>) new Dictionary<string, object>(),
                                                   (IOutputData) data);
            e.Responses[dev1] = new Response();

            c.EnqueueEpoch(e);
            c.NextEpoch();
            c.PushInputData(dev1, new InputData(samples.Concat(samples).ToList(),
                sampleRate,
                DateTimeOffset.Now)
                .DataWithStreamConfiguration(streamFake, new Dictionary<string, object>())
                .DataWithExternalDeviceConfiguration(devFake, new Dictionary<string, object>()));

            Assert.That(((TimeSpan)e.Responses[dev1].Duration), Is.EqualTo((TimeSpan)e.Duration));
        }
        private static void OrderedFakeInputData(out IInputData d1, out IInputData d2)
        {
            Random random = new Random();
            IList<IMeasurement> data = (IList<IMeasurement>) Enumerable.Repeat(0, 100).Select(i => random.Next()).Select(v => new Measurement(v, "V") as IMeasurement).ToList(); ;//generate random data
            IMeasurement srate = new Measurement(1000, "Hz");
            DateTimeOffset time1 = DateTimeOffset.Now;
            IDictionary<string, object> config = new Dictionary<string, object>();
            var dev = new UnitConvertingExternalDevice("DevName", "DevManufacturer", new Measurement(0, "V"));
            var stream = new DAQOutputStream("StreamName");

            d1 = new InputData(data, srate, time1)
                .DataWithExternalDeviceConfiguration(dev, config)
                .DataWithStreamConfiguration(stream, config);

            DateTimeOffset time2 = time1.AddSeconds((double) (data.Count / srate.Quantity));
            d2 = new InputData(data, srate, time2)
                .DataWithExternalDeviceConfiguration(dev, config)
                .DataWithStreamConfiguration(stream, config);
        }
        public void PreventsDuplicateExternalDeviceNames()
        {
            Controller c = new Controller();

            const string UNUSED_NAME = "UNUSED";
            var dev1 = new UnitConvertingExternalDevice(UNUSED_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND);
            var dev2 = new UnitConvertingExternalDevice(UNUSED_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND);

            c.AddDevice(dev1).AddDevice(dev2);
        }
        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 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 EpochValidates()
        {
            var c = new Controller();

            var e = new Epoch(UNUSED_PROTOCOL);
            var dev2 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            var sampleRate = new Measurement(1, "Hz");

            e.Stimuli[dev2] = new DelegatedStimulus("ID2", "units",
                                                    new Dictionary<string, object>(),
                                                    (x, y) => null,
                                                    (p) => Option<TimeSpan>.None());

            try
            {
                Assert.That(() => c.RunEpoch(e, new FakeEpochPersistor()), Throws.Nothing);
            }
            catch (Exception)
            {
                //pass
            }
        }
        public void NextEpochShouldFireNextEpochEvent()
        {
            var c = new Controller();
            c.Clock = new FakeClock();

            var e = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            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);

            e.Stimuli[dev1] = new RenderedStimulus((string) "ID1",
                                                   (IDictionary<string, object>) new Dictionary<string, object>(),
                                                   (IOutputData) data);
            e.Responses[dev1] = new Response();

            c.EnqueueEpoch(e);

            bool evt = false;
            c.NextEpochRequested += (sender, args) => evt = true;

            c.NextEpoch();

            Assert.True(evt);
        }
        public void MaybeHasStartTime()
        {
            Epoch e = new Epoch("");

            Assert.False(e.StartTime);

            var dev = new UnitConvertingExternalDevice("name", "co", new Measurement(1.0m, "units"));

            var stim = new DelegatedStimulus("stimID", "units", new Measurement(1000, "Hz"),
                                             new Dictionary<string, object>(),
                                             (p, b) => null,
                                             (p) => Option<TimeSpan>.None());

            e.Stimuli[dev] = stim;

            var expected = DateTimeOffset.Now;

            stim.DidOutputData(expected, TimeSpan.FromSeconds(1), null);

            Assert.AreEqual(expected, (DateTimeOffset)e.StartTime);
        }
        public void PushesDataToEpoch()
        {
            const string UNUSED_NAME = "UNUSED";

            var c = new SingleEpochController();
            var dev = new UnitConvertingExternalDevice(UNUSED_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND);
            c.AddDevice(dev);

            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));

            c.SetCurrentEpoch(e);

            var streamFake = new DAQInputStream("StreamFake");

            var data = new InputData(samples, srate, DateTimeOffset.Now)
                .DataWithStreamConfiguration(streamFake, new Dictionary<string, object>());

            c.PushInputData(dev, data);

            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(streamFake.Name)));
        }
        public void PushesStimulusConfigurationSpansToEpoch()
        {
            const string UNUSED_NAME = "UNUSED";

            var c = new SingleEpochController();
            var dev = new UnitConvertingExternalDevice(UNUSED_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND);

            var outputTime = DateTimeOffset.Now;
            var configuration = new List<IPipelineNodeConfiguration>();
            var config = new Dictionary<string, object>();
            config["key"] = "value";

            configuration.Add(new PipelineNodeConfiguration(UNUSED_NAME, config));

            var epochMock = new Mock<Epoch>("test-epoch");
            epochMock.Setup(epoch => epoch.DidOutputData(dev, outputTime, TimeSpan.FromSeconds(0.1), configuration)).AtMostOnce();
            epochMock.Setup(epoch => epoch.IsComplete).Returns(false);

            c.SetCurrentEpoch(epochMock.Object);

            c.DidOutputData(dev, outputTime, TimeSpan.FromSeconds(0.1), configuration);

            epochMock.Verify(epoch => epoch.DidOutputData(dev, outputTime, TimeSpan.FromSeconds(0.1), configuration));
        }
        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 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 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 NexEpochShouldDequeueEpoch()
        {
            var c = new Controller();

            var e = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            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);

            e.Stimuli[dev1] = new RenderedStimulus((string) "ID1",
                                                   (IDictionary<string, object>) new Dictionary<string, object>(),
                                                   (IOutputData) data);
            e.Responses[dev1] = new Response();

            c.EnqueueEpoch(e);

            Assert.That(c.CurrentEpoch, Is.Null);

            c.NextEpoch();

            Assert.That(c.CurrentEpoch, Is.EqualTo(e));
        }
        public void RunEpochThrowsGivenEpochWithInconsistentStimulusDurations()
        {
            var c = new Controller();

            var e = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev1", "co", c, new Measurement(0, "V"));
            var dev2 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            var sampleRate = new Measurement(1, "Hz");

            e.Stimuli[dev1] = new RenderedStimulus((string) "ID1",
                                                   (IDictionary<string, object>) new Dictionary<string, object>(),
                                                   (IOutputData) new OutputData(new List<IMeasurement> { new Measurement(1, "V") },
                                                                                sampleRate, true));

            e.Stimuli[dev2] = new RenderedStimulus((string) "ID2",
                                                   (IDictionary<string, object>) new Dictionary<string, object>(),
                                                   (IOutputData) new OutputData(new List<IMeasurement> { new Measurement(1, "V"), new Measurement(1, "V") },
                                                                                sampleRate, true));

            Assert.That(() => c.RunEpoch(e, new FakeEpochPersistor()), Throws.Exception.TypeOf<ArgumentException>());

            e.Stimuli[dev2] = new DelegatedStimulus("ID2", "V",
                                                    new Dictionary<string, object>(),
                                                    (x, y) => null,
                                                    (p) => Option<TimeSpan>.None());

            Assert.That(() => c.RunEpoch(e, new FakeEpochPersistor()), Throws.Exception.TypeOf<ArgumentException>());
        }
        private static Epoch CreateTestEpoch(out ExternalDeviceBase dev1, out ExternalDeviceBase dev2)
        {
            dev1 = new UnitConvertingExternalDevice("dev1", "man1", new Measurement(0, "V"));
            dev2 = new UnitConvertingExternalDevice("dev2", "man2", new Measurement(0, "V"));

            var stream1 = new DAQInputStream("Stream1");
            var stream2 = new DAQInputStream("Stream2");

            var stimParameters = new Dictionary<string, object>();
            stimParameters["param1"] = 1;
            stimParameters["param2"] = 2;

            var srate = new Measurement(1000, "Hz");

            List<Measurement> samples =
                Enumerable.Range(0, 10000).Select(i => new Measurement((decimal)Math.Sin((double)i / 100), "V")).ToList();
            var stimData = new OutputData(samples, srate, false);

            var stim1 = new RenderedStimulus("RenderedStimulus", stimParameters, stimData);
            var stim2 = new RenderedStimulus("RenderedStimulus", stimParameters, stimData)
                {
                    ShouldDataBePersisted = true
                };

            var protocolParameters = new Dictionary<string, object>
                {
                    {"one", 1},
                    {"two", "second"},
                    {"three", 5.55}
                };

            var epoch = new TestEpoch("protocol.banana", protocolParameters);
            epoch.Stimuli[dev1] = stim1;
            epoch.Stimuli[dev2] = stim2;

            DateTimeOffset start = DateTimeOffset.Now;
            epoch.SetStartTime(Maybe<DateTimeOffset>.Yes(start));

            epoch.Backgrounds[dev1] = new Background(new Measurement(0, "V"), new Measurement(1000, "Hz"));
            epoch.Backgrounds[dev2] = new Background(new Measurement(1, "V"), new Measurement(1000, "Hz"));

            epoch.Responses[dev1] = new Response();
            epoch.Responses[dev2] = new Response();

            var streamConfig = new Dictionary<string, object>();
            streamConfig["configParam1"] = 1;

            var devConfig = new Dictionary<string, object>();
            devConfig["configParam2"] = 2;

            IInputData responseData1 = new InputData(samples, srate, start)
                .DataWithStreamConfiguration(stream1, streamConfig)
                .DataWithExternalDeviceConfiguration(dev1, devConfig);
            IInputData responseData2 = new InputData(samples, srate, start + TimeSpanExtensions.FromSamples((uint) samples.Count, srate))
                .DataWithStreamConfiguration(stream1, streamConfig)
                .DataWithExternalDeviceConfiguration(dev1, devConfig);

            IInputData responseData3 = new InputData(samples, srate, start)
                .DataWithStreamConfiguration(stream2, streamConfig)
                .DataWithExternalDeviceConfiguration(dev2, devConfig);
            IInputData responseData4 = new InputData(samples, srate, start + TimeSpanExtensions.FromSamples((uint)samples.Count, srate))
                .DataWithStreamConfiguration(stream2, streamConfig)
                .DataWithExternalDeviceConfiguration(dev2, devConfig);

            epoch.Responses[dev1].AppendData(responseData1);
            epoch.Responses[dev1].AppendData(responseData2);

            epoch.Responses[dev2].AppendData(responseData3);
            epoch.Responses[dev2].AppendData(responseData4);

            epoch.Properties.Add("prop1", 5);
            epoch.Properties.Add("prop2", "banana");

            epoch.Keywords.Add("word1");
            epoch.Keywords.Add("word2");

            return epoch;
        }
        public void RunEpochThrowsGivenIndefiniteEpochWithResponses()
        {
            var c = new Controller();

            var e = new Epoch(UNUSED_PROTOCOL);
            var dev2 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            var sampleRate = new Measurement(1, "Hz");

            e.Stimuli[dev2] = new DelegatedStimulus("ID2", "units",
                                                    new Dictionary<string, object>(),
                                                    (x, y) => null,
                                                    (p) => Option<TimeSpan>.None());
            e.Responses[dev2] = new Response();

            Assert.That(() => c.RunEpoch(e, new FakeEpochPersistor()), Throws.Exception.TypeOf<ArgumentException>());
        }
        public void GetDeivceReturnsDevice()
        {
            Controller c = new Controller();

            const string DEVICE_NAME = "DEVICE";
            var dev1 = new UnitConvertingExternalDevice(DEVICE_NAME, UNUSED_DEVICE_MANUFACTURER, UNUSED_BACKGROUND);

            c.AddDevice(dev1);

            Assert.AreEqual(dev1, c.GetDevice(DEVICE_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 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 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());
        }
        public void RunEpochShouldDiscardEpochWhenCancelEpochCalled()
        {
            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 e = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev1", "co", c, new Measurement(0, "V"))
                           {
                               MeasurementConversionTarget = "V",
                               Clock = c.Clock
                           };

            var sampleRate = new Measurement(1, "Hz");

            e.Stimuli[dev1] = new DelegatedStimulus("ID1", "units", 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.CancelEpoch();
                                       };

            c.RunEpoch(e, new FakeEpochPersistor());

            Assert.True(epochDiscarded);
        }
        public void NextEpochThrowsIfCannotDequeue()
        {
            var c = new Controller();

            var e = new Epoch(UNUSED_PROTOCOL);
            var dev1 = new UnitConvertingExternalDevice("dev2", "co", c, new Measurement(0, "V"));

            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);

            e.Stimuli[dev1] = new RenderedStimulus((string) "ID1",
                                                   (IDictionary<string, object>) new Dictionary<string, object>(),
                                                   (IOutputData) data);
            e.Responses[dev1] = new Response();

            c.EnqueueEpoch(e);

            c.NextEpoch();

            Assert.Throws<SymphonyControllerException>(() => c.NextEpoch());
        }