public void PullsOutput()
        {
            TimeSpan loopDuration = TimeSpan.FromMilliseconds(IterationMilliseconds);

            SimulationDAQController c = new SimulationDAQController(loopDuration);
            c.Clock = new FakeClock();

            IOutputData expectedOutput;
            DAQOutputStream outStream;
            SetupOutputPipeline(c, out expectedOutput, out outStream);

            IDictionary<IDAQOutputStream, IOutputData> actualOutput = null;
            TimeSpan actualTimeStep = TimeSpan.FromMilliseconds(0);

            c.SimulationRunner = (IDictionary<IDAQOutputStream, IOutputData> output, TimeSpan timeStep) =>
            {
                actualOutput = output;
                actualTimeStep = timeStep;

                return new Dictionary<IDAQInputStream, IInputData>();
            };

            c.ProcessIteration += (controller, evtArgs) =>
            {
                ((Symphony.Core.IDAQController)controller).Stop();
            };
            c.Start(false);

            while (c.Running) { }

            Assert.AreEqual(loopDuration, actualTimeStep);
            CollectionAssert.AreEqual(actualOutput[outStream].Data, expectedOutput.SplitData(loopDuration).Head.Data);
        }
        public void PushesInput()
        {
            TimeSpan loopDuration = TimeSpan.FromMilliseconds(IterationMilliseconds);

            var c = new SimulationDAQController(loopDuration) { Clock = new FakeClock() };

            IOutputData expectedOutput;
            DAQOutputStream outStream;
            DAQInputStream inStream;
            SetupInputPipeline(c, out expectedOutput, out outStream, out inStream);

            c.SimulationRunner = (IDictionary<IDAQOutputStream, IOutputData> output, TimeSpan timeStep) =>
            {
                var inputData = new Dictionary<IDAQInputStream, IInputData>(1);
                expectedOutput = output[outStream];
                inputData[inStream] = new InputData(expectedOutput.Data, expectedOutput.SampleRate, DateTimeOffset.Now);

                return inputData;
            };

            c.ProcessIteration += (controller, evtArgs) => ((IDAQController)controller).Stop();
            bool stopped = false;
            c.Stopped += (controller, evtArgs) =>
                             {
                                 stopped = true;
                             };
            c.Start(false);
            Thread.Sleep(500);

            var actualInput = ((TestDevice)outStream.Device).InputData.ContainsKey(inStream) ? ((TestDevice)outStream.Device).InputData[inStream].First() : null;

            Assert.That(actualInput, Is.Not.Null);
            Assert.That(actualInput.Data, Is.EqualTo(expectedOutput.Data));
        }
        public void PushesInput()
        {
            TimeSpan loopDuration = TimeSpan.FromMilliseconds(IterationMilliseconds);

            var c = new SimulationDAQController(loopDuration)
            {
                Clock = new FakeClock()
            };

            IOutputData     expectedOutput;
            DAQOutputStream outStream;
            DAQInputStream  inStream;

            SetupInputPipeline(c, out expectedOutput, out outStream, out inStream);


            c.SimulationRunner = (IDictionary <IDAQOutputStream, IOutputData> output, TimeSpan timeStep) =>
            {
                var inputData = new Dictionary <IDAQInputStream, IInputData>(1);
                expectedOutput      = output[outStream];
                inputData[inStream] = new InputData(expectedOutput.Data, expectedOutput.SampleRate, DateTimeOffset.Now);

                return(inputData);
            };

            c.ProcessIteration += (controller, evtArgs) => ((IDAQController)controller).Stop();
            bool stopped = false;

            c.Stopped += (controller, evtArgs) =>
            {
                stopped = true;
            };
            c.Start(false);
            Thread.Sleep(500);

            var actualInput = ((TestDevice)outStream.Device).InputData.ContainsKey(inStream) ? ((TestDevice)outStream.Device).InputData[inStream].First() : null;

            Assert.That(actualInput, Is.Not.Null);
            Assert.That(actualInput.Data, Is.EqualTo(expectedOutput.Data));
        }
        public void PullsOutput()
        {
            TimeSpan loopDuration = TimeSpan.FromMilliseconds(IterationMilliseconds);

            SimulationDAQController c = new SimulationDAQController(loopDuration);

            c.Clock = new FakeClock();

            IOutputData     expectedOutput;
            DAQOutputStream outStream;

            SetupOutputPipeline(c, out expectedOutput, out outStream);

            IDictionary <IDAQOutputStream, IOutputData> actualOutput = null;
            TimeSpan actualTimeStep = TimeSpan.FromMilliseconds(0);

            c.SimulationRunner = (IDictionary <IDAQOutputStream, IOutputData> output, TimeSpan timeStep) =>
            {
                actualOutput   = output;
                actualTimeStep = timeStep;

                return(new Dictionary <IDAQInputStream, IInputData>());
            };

            c.ProcessIteration += (controller, evtArgs) =>
            {
                ((Symphony.Core.IDAQController)controller).Stop();
            };
            c.Start(false);

            while (c.Running)
            {
            }

            Assert.AreEqual(loopDuration, actualTimeStep);
            CollectionAssert.AreEqual(actualOutput[outStream].Data, expectedOutput.SplitData(loopDuration).Head.Data);
        }
        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;
        }