public void MultipleEpochs(
            [Values(1000, 5000, 10000, 20000)] double sampleRate
            )
        {
            Epoch                e;
            IExternalDevice      dev0;
            RenderedStimulus     stim1;
            IExternalDevice      dev1;
            RenderedStimulus     stim2;
            IList <IMeasurement> stimData;
            var controller = SetupController(sampleRate, out e, out dev0, out stim1, out dev1, out stim2, out stimData, 2);

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

            var          inputData        = e.Responses[dev0].Data;
            const double MAX_VOLTAGE_DIFF = 0.001;
            int          failures         = inputData.Select((t, i) => t.QuantityInBaseUnit - stimData[i].QuantityInBaseUnit)
                                            .Count(dif => Math.Abs(dif) > (decimal)MAX_VOLTAGE_DIFF);

            Assert.AreEqual(0, failures);

            e    = new Epoch("LowGainSimulation");
            dev0 = controller.GetDevice("Device0");
            dev1 = controller.GetDevice("Device1");

            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;
            e.Stimuli[dev1] = stim2;

            e.Responses[dev0] = new Response();
            e.Responses[dev1] = new Response();

            e.Background[dev1] = new Epoch.EpochBackground(new Measurement(0, "V"), srate);
            e.Background[dev0] = new Epoch.EpochBackground(new Measurement(0, "V"), srate);

            Assert.DoesNotThrow(() => controller.RunEpoch(e, new FakeEpochPersistor()));

            inputData = e.Responses[dev0].Data;
            failures  = inputData.Select((t, i) => t.QuantityInBaseUnit - stimData[i].QuantityInBaseUnit)
                        .Count(dif => Math.Abs(dif) > (decimal)MAX_VOLTAGE_DIFF);


            Assert.AreEqual(0, failures);
        }
Exemplo n.º 2
0
        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;
                    controller.DAQController = daq;


                    const decimal expectedBackgroundVoltage = -3.2m;
                    var           expectedBackground        = new Measurement(expectedBackgroundVoltage, "V");
                    var           dev0 = new UnitConvertingExternalDevice("Device0", "Manufacturer", controller, expectedBackground)
                    {
                        MeasurementConversionTarget = "V"
                    };
                    dev0.BindStream(daq.GetStreams("ANALOG_OUT.0").First() as IDAQOutputStream);
                    dev0.BindStream(daq.GetStreams("ANALOG_IN.0").First() as IDAQInputStream);
                    dev0.Clock = daq;

                    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.Background[dev0] = new Epoch.EpochBackground(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).ReadStreamAsyncIO(
                        daq.GetStreams("ANALOG_IN.0").First() as IDAQInputStream);

                    //Should be within +/- 0.025 volts
                    Assert.That(actual.Data.First().QuantityInBaseUnit, Is.InRange(expectedBackground.QuantityInBaseUnit - (decimal)0.025,
                                                                                   expectedBackground.QuantityInBaseUnit + (decimal)0.025));
                }
                finally
                {
                    if (daq.HardwareReady)
                    {
                        daq.CloseHardware();
                    }
                }
            }
        }
        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);

            var streamNameMap = new Dictionary <string, string>();

            streamNameMap["Out0"] = "In0";
            if (nChannels > 1)
            {
                streamNameMap["Out1"] = "In1";
            }

            Controller controller = new Parser().ParseConfiguration(Resources.LowGainConfig);

            var daq = (SimulationDAQController)controller.DAQController;

            daq.Clock = daq;
            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,
                                               DateTimeOffset.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 = controller.GetDevice("Device0");
            dev1 = controller.GetDevice("Device1");

            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.Background[dev1] = new Epoch.EpochBackground(new Measurement(0, "V"), srate);
            e.Background[dev0] = new Epoch.EpochBackground(new Measurement(0, "V"), srate);

            return(controller);
        }