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