public void ShouldDiscardAllButMostRecentStaleInputParametersAfterStalenessInterval()
        {
            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY);

            mcd.BindStream(new DAQInputStream(UNUSED_NAME));

            var data1     = new MultiClampInterop.MulticlampData();
            var expected2 = new MultiClampInterop.MulticlampData();
            var expected  = new MultiClampInterop.MulticlampData();

            var marker = DateTimeOffset.Now.ToUniversalTime();

            mc.FireParametersChanged(marker.Subtract(TimeSpan.FromSeconds(MultiClampDevice.ParameterStalenessInterval.TotalSeconds * 3)), data1);
            mc.FireParametersChanged(marker.Subtract(TimeSpan.FromSeconds(MultiClampDevice.ParameterStalenessInterval.TotalSeconds * 2)), expected);
            mc.FireParametersChanged(marker, expected2);

            Assert.That(((MultiClampParametersChangedArgs)mcd.DeviceParametersForInput(DateTimeOffset.Now)).Data,
                        Is.EqualTo(expected2));


            var oldTime = DateTimeOffset.Now.Subtract(MultiClampDevice.ParameterStalenessInterval);

            Assert.That(((MultiClampParametersChangedArgs)mcd.DeviceParametersForInput(oldTime)).Data,
                        Is.EqualTo(expected));

            var veryOldTime = marker.Subtract(TimeSpan.FromSeconds(MultiClampDevice.ParameterStalenessInterval.TotalSeconds * 3));

            Assert.Throws <MultiClampDeviceException>(() => mcd.DeviceParametersForInput(veryOldTime));
        }
        public void ShouldConvertOutputUnitsInIClamp(
            [Values(MultiClampInterop.OperatingMode.I0, MultiClampInterop.OperatingMode.IClamp)] MultiClampInterop.OperatingMode operatingMode
            )
        {
            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c,
                                           new Dictionary <MultiClampInterop.OperatingMode, IMeasurement>()
            {
                { operatingMode, UNUSED_BACKGROUND }
            }
                                           );

            var data = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = operatingMode,
                ExternalCommandSensitivity      = 2.5,
                ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.A_V
            };

            mc.FireParametersChanged(DateTimeOffset.Now, data);

            var cmd = new Measurement(20, -12, "A");

            var expected = operatingMode == MultiClampInterop.OperatingMode.I0 ?
                           new Measurement(0, "V") :
                           new Measurement(cmd.QuantityInBaseUnit / (decimal)data.ExternalCommandSensitivity,
                                           cmd.Exponent, "V");

            var actual = MultiClampDevice.ConvertOutput(cmd, data);

            Assert.That(actual, Is.EqualTo(expected));
        }
        public void ShouldAllowBackgroundDefinitionViaString()
        {
            const string VClampUnits = "V";
            const string IClampUnits = "A";

            Measurement VClampBackground = new Measurement(2, -3, VClampUnits);
            Measurement IClampBackground = new Measurement(-10, -3, IClampUnits);

            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var bg = new Dictionary <MultiClampInterop.OperatingMode, IMeasurement>()
            {
                { MultiClampInterop.OperatingMode.VClamp, VClampBackground },
                { MultiClampInterop.OperatingMode.IClamp, IClampBackground },
            };

            var mcd = new MultiClampDevice(mc.SerialNumber, mc.Channel, c.Clock, c, new List <string>()
            {
                "VClamp", "IClamp"
            }, bg.Values);

            Assert.That(mcd.BackgroudForMode(MultiClampInterop.OperatingMode.VClamp), Is.EqualTo(VClampBackground));
            Assert.That(mcd.BackgroudForMode(MultiClampInterop.OperatingMode.IClamp), Is.EqualTo(IClampBackground));
        }
        public void ShouldAllowBackgroundValueChangeAfterConstruction()
        {
            const string units = "V";

            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var bg            = new Measurement(2, -3, units);
            var operatingMode = MultiClampInterop.OperatingMode.VClamp;
            var background    = new Dictionary <MultiClampInterop.OperatingMode, IMeasurement>()
            {
                { operatingMode, bg }
            };

            var mcd = new MultiClampDevice(mc, c, background);

            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            var data = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = operatingMode,
                ExternalCommandSensitivity      = 2.5,
                ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.V_V
            };

            mc.FireParametersChanged(DateTimeOffset.Now, data);

            var newBackground = new Measurement(10, -3, units);

            mcd.Background = newBackground;

            var expected = new Measurement(newBackground.QuantityInBaseUnit / (decimal)data.ExternalCommandSensitivity, newBackground.Exponent, "V");

            Assert.That(mcd.OutputBackground, Is.EqualTo(expected));
        }
        public void ShouldThrowExceptionConvertingOutputGivenEmptyParametersQueue()
        {
            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY);


            Assert.Throws <MultiClampDeviceException>(() => mcd.ConvertOutput(new Measurement(0, "V"), DateTimeOffset.Now));
        }
        public void ShouldThrowExceptionConvertingInputGivenNoParametersForTime()
        {
            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY);

            mcd.BindStream(new DAQInputStream(UNUSED_NAME));

            mc.FireParametersChanged(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1)), new MultiClampInterop.MulticlampData());


            Assert.Throws <MultiClampDeviceException>(() => mcd.ConvertInput(new Measurement(0, "V"), DateTimeOffset.Now));
        }
        public void ShouldThrowForUnexpectedScaleFactorUnitsWhenExpectingVolts(
            [Values(new object[]
        {
            MultiClampInterop.ScaleFactorUnits.V_A,
            MultiClampInterop.ScaleFactorUnits.V_mA,
            MultiClampInterop.ScaleFactorUnits.V_nA,
            MultiClampInterop.ScaleFactorUnits.V_uA,
            MultiClampInterop.ScaleFactorUnits.V_pA
        })] MultiClampInterop.ScaleFactorUnits scaleFactorUnits,
            [Values(new object[]
        {
            MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_V_MEMBx10,
            MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_V_MEMBx100,
            MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_VC_GLDR_V_CMD_EXT,
            MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_VC_GLDR_V_CMD_MEMB,
            MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_VC_GLDR_V_CMD_SUMMED
        })] MultiClampInterop.SignalIdentifier signalIdentifier
            )
        {
            MultiClampInterop.OperatingMode mode;
            switch (signalIdentifier)
            {
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_VC_GLDR_V_CMD_EXT:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_VC_GLDR_V_CMD_MEMB:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_VC_GLDR_V_CMD_SUMMED:
                mode = MultiClampInterop.OperatingMode.VClamp;
                break;

            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_V_MEMBx10:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_V_MEMBx100:
                mode = MultiClampInterop.OperatingMode.IClamp;
                break;

            default:
                throw new ArgumentOutOfRangeException("signalIdentifier");
            }

            var data = new MultiClampInterop.MulticlampData()
            {
                ScaledOutputSignal = signalIdentifier,
                ScaleFactorUnits   = scaleFactorUnits,
                OperatingMode      = mode
            };


            Assert.Throws <MultiClampDeviceException>(() => MultiClampDevice.ConvertInput(UNUSED_MEASUREMENT, data),
                                                      scaleFactorUnits +
                                                      " is not an allowed unit conversion for scaled output mode.");
        }
        public void ShouldProvideCurrentOutputParameters()
        {
            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY);

            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            var expected = new MultiClampInterop.MulticlampData();

            mc.FireParametersChanged(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1)), expected);

            Assert.That(mcd.CurrentDeviceOutputParameters.Data,
                        Is.EqualTo(expected));
        }
        public void ShouldThrowForUnexpectedScaleFactorUnitsWhenExpectingAmps(
            [Values(new object[]
        {
            MultiClampInterop.ScaleFactorUnits.V_mV,
            MultiClampInterop.ScaleFactorUnits.V_uV,
            MultiClampInterop.ScaleFactorUnits.V_V
        })] MultiClampInterop.ScaleFactorUnits scaleFactorUnits,
            [Values(new object[]
        {
            MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_VC_GLDR_I_MEMB,
            MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_I_CMD_MEMB,
            MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_I_CMD_SUMMED
        })] MultiClampInterop.SignalIdentifier signalIdentifier
            )
        {
            var mc = new FakeMulticlampCommander();

            MultiClampInterop.OperatingMode mode;
            switch (signalIdentifier)
            {
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_VC_GLDR_I_MEMB:
                mode = MultiClampInterop.OperatingMode.VClamp;
                break;

            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_I_CMD_MEMB:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_I_CMD_SUMMED:
                mode = MultiClampInterop.OperatingMode.IClamp;
                break;

            default:
                throw new ArgumentOutOfRangeException("signalIdentifier");
            }

            var data = new MultiClampInterop.MulticlampData()
            {
                ScaledOutputSignal = signalIdentifier,
                ScaleFactorUnits   = scaleFactorUnits,
                OperatingMode      = mode
            };

            Assert.Throws <MultiClampDeviceException>(
                () => MultiClampDevice.ConvertInput(new Measurement(1.0m, "A"), data));
        }
        public void ShouldUseBackgroundForMode()
        {
            const string VClampUnits = "V";
            const string IClampUnits = "A";

            Measurement VClampBackground = new Measurement(2, -3, VClampUnits);
            Measurement IClampBackground = new Measurement(-10, -3, IClampUnits);

            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var bg = new Dictionary <MultiClampInterop.OperatingMode, IMeasurement>()
            {
                { MultiClampInterop.OperatingMode.VClamp, VClampBackground },
                { MultiClampInterop.OperatingMode.IClamp, IClampBackground },
            };

            var mcd = new MultiClampDevice(mc, c, bg);

            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            var data = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = MultiClampInterop.OperatingMode.VClamp,
                ExternalCommandSensitivity      = 2.5,
                ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.V_V
            };

            mc.FireParametersChanged(DateTimeOffset.Now, data);

            Assert.That(mcd.OutputBackground, Is.EqualTo(MultiClampDevice.ConvertOutput(VClampBackground, mcd.CurrentDeviceOutputParameters.Data)));

            data = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = MultiClampInterop.OperatingMode.IClamp,
                ExternalCommandSensitivity      = 1.5,
                ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.A_V
            };

            mc.FireParametersChanged(DateTimeOffset.Now, data);

            Assert.That(mcd.OutputBackground, Is.EqualTo(MultiClampDevice.ConvertOutput(IClampBackground, mcd.CurrentDeviceOutputParameters.Data)));
        }
        public void ShouldTakeMostRecentParametersForInput()
        {
            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY);

            mcd.BindStream(new DAQInputStream(UNUSED_NAME));

            var data1    = new MultiClampInterop.MulticlampData();
            var expected = new MultiClampInterop.MulticlampData();
            var data3    = new MultiClampInterop.MulticlampData();

            mc.FireParametersChanged(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1)), data1);
            mc.FireParametersChanged(DateTimeOffset.Now.Subtract(TimeSpan.FromMilliseconds(1)), expected);
            mc.FireParametersChanged(DateTimeOffset.Now.Add(TimeSpan.FromHours(1)), data3);

            Assert.That(((MultiClampParametersChangedArgs)mcd.DeviceParametersForInput(DateTimeOffset.Now)).Data,
                        Is.EqualTo(expected));
        }
        public void ShouldConvertOutputUnitsInVClamp(
            [Values(MultiClampInterop.OperatingMode.VClamp)] MultiClampInterop.OperatingMode operatingMode
            )
        {
            var data = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = operatingMode,
                ExternalCommandSensitivity      = 2.5,
                ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.V_V
            };

            var cmd = new Measurement(20, -3, "V");

            var expected = new Measurement(cmd.QuantityInBaseUnit / (decimal)data.ExternalCommandSensitivity,
                                           cmd.Exponent, "V");

            var actual = MultiClampDevice.ConvertOutput(cmd, data);

            Assert.That(actual, Is.EqualTo(expected));
        }
        public void ShouldNotApplyBackgroundToRunningStreams()
        {
            const string units = "V";
            const MultiClampInterop.OperatingMode vclampMode = MultiClampInterop.OperatingMode.VClamp;
            const MultiClampInterop.OperatingMode iclampMode = MultiClampInterop.OperatingMode.IClamp;


            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var vclampBackground = new Measurement(2, -3, units);

            var background = new Dictionary <MultiClampInterop.OperatingMode, IMeasurement>()
            {
                { vclampMode, vclampBackground }
            };

            var dataVClamp = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = vclampMode,
                ExternalCommandSensitivity      = 2.5,
                ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.V_V
            };


            var daq = new DynamicMock(typeof(IDAQController));
            var s   = new DAQOutputStream("test", daq.MockInstance as IDAQController);


            var mcd = new MultiClampDevice(mc, c, background);

            mcd.BindStream(s);

            daq.ExpectAndReturn("get_Running", true);
            daq.ExpectNoCall("ApplyStreamBackground");

            mc.FireParametersChanged(DateTimeOffset.Now, dataVClamp);

            daq.Verify();
        }
        private void BackgroundTest(MultiClampInterop.OperatingMode operatingMode,
                                    string units,
                                    MultiClampInterop.ExternalCommandSensitivityUnits extSensUnits)
        {
            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var bg = new Measurement(2, -3, units);

            var background = new Dictionary <MultiClampInterop.OperatingMode, IMeasurement>()
            {
                { operatingMode, bg }
            };
            var mcd = new MultiClampDevice(mc, c, background);

            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            var data = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = operatingMode,
                ExternalCommandSensitivity      = 2.5,
                ExternalCommandSensitivityUnits = extSensUnits
            };

            mc.FireParametersChanged(DateTimeOffset.Now, data);


            var expected = operatingMode == MultiClampInterop.OperatingMode.I0 ?
                           new Measurement(0, "V") :
                           new Measurement(bg.QuantityInBaseUnit / (decimal)data.ExternalCommandSensitivity, bg.Exponent, "V");

            mc.FireParametersChanged(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1)), data);

            var actual = mcd.OutputBackground;

            Assert.That(actual, Is.EqualTo(expected));
        }
        public void ShouldSetBackgroundForMode()
        {
            const string units = "V";

            var c  = new Controller();
            var mc = new FakeMulticlampCommander();

            var VClampBackground = new Measurement(2, -3, units);
            var operatingMode    = MultiClampInterop.OperatingMode.VClamp;
            var background       = new Dictionary <MultiClampInterop.OperatingMode, IMeasurement>()
            {
                { operatingMode, VClampBackground }
            };

            var mcd = new MultiClampDevice(mc, c, background);

            var IClampMode       = MultiClampInterop.OperatingMode.IClamp;
            var IClampBackground = new Measurement(-1, "A");

            mcd.SetBackgroundForMode(IClampMode, IClampBackground);

            Assert.That(mcd.BackgroudForMode(IClampMode), Is.EqualTo(IClampBackground));
            Assert.That(mcd.BackgroudForMode(operatingMode), Is.EqualTo(VClampBackground));
        }
        public void ShouldThrowExceptionConvertingOutputGivenNoParametersForTime()
        {
            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY);
            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            mc.FireParametersChanged(DateTimeOffset.Now.Add(TimeSpan.FromHours(1)), new MultiClampInterop.MulticlampData());

            Assert.Throws<MultiClampDeviceException>(() => mcd.ConvertOutput(new Measurement(0, "V"), DateTimeOffset.Now));
        }
        public void ShouldTakeMostRecentParametersForOutput()
        {
            var data1 = new MultiClampInterop.MulticlampData();
            var expected = new MultiClampInterop.MulticlampData();
            var data3 = new MultiClampInterop.MulticlampData();

            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY);
            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            mc.FireParametersChanged(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1)), data1);
            mc.FireParametersChanged(DateTimeOffset.Now.Subtract(TimeSpan.FromMilliseconds(1)), expected);
            mc.FireParametersChanged(DateTimeOffset.Now.Add(TimeSpan.FromHours(1)), data3);

            Assert.That(((MultiClampParametersChangedArgs)mcd.DeviceParametersForOutput(DateTimeOffset.Now)).Data,
                Is.EqualTo(expected));
        }
        public void ShouldThrowExceptionConvertingOutputGivenEmptyParametersQueue()
        {
            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY);

            Assert.Throws<MultiClampDeviceException>(() => mcd.ConvertOutput(new Measurement(0, "V"), DateTimeOffset.Now));
        }
        public void ShouldProvideCurrentOutputParametersAfterMultipleParameterChangedEvents()
        {
            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY);
            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            var data1 = new MultiClampInterop.MulticlampData();
            var expected = new MultiClampInterop.MulticlampData();

            mc.FireParametersChanged(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1)), data1);
            mc.FireParametersChanged(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1)), expected);

            Assert.That(mcd.CurrentDeviceOutputParameters.Data,
                Is.EqualTo(expected));
        }
        public void ShouldSetBackgroundForMode()
        {
            const string units = "V";

            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var VClampBackground = new Measurement(2, -3, units);
            var operatingMode = MultiClampInterop.OperatingMode.VClamp;
            var background = new Dictionary<MultiClampInterop.OperatingMode, IMeasurement>() { { operatingMode, VClampBackground } };

            var mcd = new MultiClampDevice(mc, c, background);

            var IClampMode = MultiClampInterop.OperatingMode.IClamp;
            var IClampBackground = new Measurement(-1, "A");

            mcd.SetBackgroundForMode(IClampMode, IClampBackground);

            Assert.That(mcd.BackgroudForMode(IClampMode), Is.EqualTo(IClampBackground));
            Assert.That(mcd.BackgroudForMode(operatingMode), Is.EqualTo(VClampBackground));
        }
        public void ShouldDiscardAllButMostRecentStaleOutputParametersAfterStalenessInterval()
        {
            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY);
            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            var data1 = new MultiClampInterop.MulticlampData();
            var expected2 = new MultiClampInterop.MulticlampData();
            var expected = new MultiClampInterop.MulticlampData();

            var marker = DateTimeOffset.Now.ToUniversalTime();

            mc.FireParametersChanged(marker.Subtract(TimeSpan.FromSeconds(MultiClampDevice.ParameterStalenessInterval.TotalSeconds * 3)), data1);
            mc.FireParametersChanged(marker.Subtract(TimeSpan.FromSeconds(MultiClampDevice.ParameterStalenessInterval.TotalSeconds * 2)), expected);
            mc.FireParametersChanged(marker, expected2);

            Assert.That(((MultiClampParametersChangedArgs)mcd.DeviceParametersForOutput(DateTimeOffset.Now)).Data,
                Is.EqualTo(expected2));

            var oldTime = DateTimeOffset.Now.Subtract(MultiClampDevice.ParameterStalenessInterval);
            Assert.That(((MultiClampParametersChangedArgs)mcd.DeviceParametersForOutput(oldTime)).Data,
                Is.EqualTo(expected));

            var veryOldTime = marker.Subtract(TimeSpan.FromSeconds(MultiClampDevice.ParameterStalenessInterval.TotalSeconds * 3));
            Assert.Throws<MultiClampDeviceException>(() => mcd.DeviceParametersForOutput(veryOldTime));
        }
        public void ShouldNotApplyBackgroundToRunningStreams()
        {
            const string units = "V";
            const MultiClampInterop.OperatingMode vclampMode = MultiClampInterop.OperatingMode.VClamp;
            const MultiClampInterop.OperatingMode iclampMode = MultiClampInterop.OperatingMode.IClamp;

            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var vclampBackground = new Measurement(2, -3, units);

            var background = new Dictionary<MultiClampInterop.OperatingMode, IMeasurement>()
                                 {
                                     { vclampMode, vclampBackground }
                                 };

            var dataVClamp = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = vclampMode,
                ExternalCommandSensitivity = 2.5,
                ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.V_V
            };

            var daq = new DynamicMock(typeof(IDAQController));
            var s = new DAQOutputStream("test", daq.MockInstance as IDAQController);

            var mcd = new MultiClampDevice(mc, c, background);
            mcd.BindStream(s);

            daq.ExpectAndReturn("get_Running", true);
            daq.ExpectNoCall("ApplyStreamBackground");

            mc.FireParametersChanged(DateTimeOffset.Now, dataVClamp);

            daq.Verify();
        }
        public void ShouldAllowBackgroundValueChangeAfterConstruction()
        {
            const string units = "V";

            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var bg = new Measurement(2, -3, units);
            var operatingMode = MultiClampInterop.OperatingMode.VClamp;
            var background = new Dictionary<MultiClampInterop.OperatingMode, IMeasurement>() { { operatingMode, bg } };

            var mcd = new MultiClampDevice(mc, c, background);
            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            var data = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = operatingMode,
                ExternalCommandSensitivity = 2.5,
                ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.V_V
            };

            mc.FireParametersChanged(DateTimeOffset.Now, data);

            var newBackground = new Measurement(10, -3, units);

            mcd.Background = newBackground;

            var expected = new Measurement(newBackground.QuantityInBaseUnit / (decimal)data.ExternalCommandSensitivity, newBackground.Exponent, "V");

            Assert.That(mcd.OutputBackground, Is.EqualTo(expected));
        }
        public void ShouldConvertOutputUnitsInIClamp(
            [Values(MultiClampInterop.OperatingMode.I0, MultiClampInterop.OperatingMode.IClamp)] MultiClampInterop.OperatingMode operatingMode
            )
        {
            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c,
                                           new Dictionary<MultiClampInterop.OperatingMode, IMeasurement>()
                                               {
                                                   {operatingMode, UNUSED_BACKGROUND}
                                               }
                );

            var data = new MultiClampInterop.MulticlampData()
                           {
                               OperatingMode = operatingMode,
                               ExternalCommandSensitivity = 2.5,
                               ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.A_V
                           };

            mc.FireParametersChanged(DateTimeOffset.Now, data);

            var cmd = new Measurement(20, -12, "A");

            var expected = operatingMode == MultiClampInterop.OperatingMode.I0 ?
                new Measurement(0, "V") :
                new Measurement(cmd.QuantityInBaseUnit / (decimal)data.ExternalCommandSensitivity,
                                           cmd.Exponent, "V");

            var actual = MultiClampDevice.ConvertOutput(cmd, data);

            Assert.That(actual, Is.EqualTo(expected));
        }
        public void ShouldAllowBackgroundDefinitionViaString()
        {
            const string VClampUnits = "V";
            const string IClampUnits = "A";

            Measurement VClampBackground = new Measurement(2, -3, VClampUnits);
            Measurement IClampBackground = new Measurement(-10, -3, IClampUnits);

            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var bg = new Dictionary<MultiClampInterop.OperatingMode, IMeasurement>()
                         {
                             {MultiClampInterop.OperatingMode.VClamp, VClampBackground},
                             {MultiClampInterop.OperatingMode.IClamp, IClampBackground},
                         };

            var mcd = new MultiClampDevice(mc.SerialNumber, mc.Channel, c.Clock, c, new List<string>() { "VClamp", "IClamp" }, bg.Values);

            Assert.That(mcd.BackgroudForMode(MultiClampInterop.OperatingMode.VClamp), Is.EqualTo(VClampBackground));
            Assert.That(mcd.BackgroudForMode(MultiClampInterop.OperatingMode.IClamp), Is.EqualTo(IClampBackground));
        }
        public void ShouldThrowExceptionConvertingInputGivenNoParametersForTime()
        {
            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY);
            mcd.BindStream(new DAQInputStream(UNUSED_NAME));

            mc.FireParametersChanged(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1)),
                new MultiClampInterop.MulticlampData()
                    {
                        HardwareType = MultiClampInterop.HardwareType.MCTG_HW_TYPE_MC700B,
                        ScaledOutputSignal700B = MultiClampInterop.SignalIdentifier700B.AXMCD_OUT_PRI_VC_GLDR_I_MEMB,
                    });

            Assert.Throws<MultiClampDeviceException>(() => mcd.ConvertInput(new Measurement(0, "V"), DateTimeOffset.Now));
        }
        public void ShouldConvertInputUnitsInIClamp(
            [Values(MultiClampInterop.OperatingMode.IClamp, MultiClampInterop.OperatingMode.I0)] MultiClampInterop.OperatingMode operatingMode,
            [Values(new object[]
        {
            MultiClampInterop.ScaleFactorUnits.V_mV,
            MultiClampInterop.ScaleFactorUnits.V_uV,
            MultiClampInterop.ScaleFactorUnits.V_V
        })] MultiClampInterop.ScaleFactorUnits scaleFactorUnits,
            [Values(1, 2, 10, 20, 100)] double alpha
            )
        {
            var data = new MultiClampInterop.MulticlampData()
            {
                OperatingMode      = operatingMode,
                ScaleFactor        = 2.5,
                ScaleFactorUnits   = scaleFactorUnits,
                ScaledOutputSignal = MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_V_MEMBx10,
                Alpha = alpha
            };

            var cmd = new Measurement(20, -3, "V");

            int exponent = 0;

            switch (scaleFactorUnits)
            {
            case MultiClampInterop.ScaleFactorUnits.V_V:
                exponent = -3;
                break;

            case MultiClampInterop.ScaleFactorUnits.V_mV:
                exponent = 0;
                break;

            case MultiClampInterop.ScaleFactorUnits.V_uV:
                exponent = 3;
                break;

            case MultiClampInterop.ScaleFactorUnits.V_A:
                exponent = -12;
                break;

            case MultiClampInterop.ScaleFactorUnits.V_mA:
                exponent = -9;
                break;

            case MultiClampInterop.ScaleFactorUnits.V_uA:
                exponent = -6;
                break;

            case MultiClampInterop.ScaleFactorUnits.V_nA:
                exponent = -3;
                break;

            case MultiClampInterop.ScaleFactorUnits.V_pA:
                exponent = 0;
                break;

            default:
                throw new ArgumentOutOfRangeException("scaleFactorUnits");
            }


            var expected = new Measurement((cmd.QuantityInBaseUnit / (decimal)data.ScaleFactor / (decimal)alpha) * (decimal)Math.Pow(10, -exponent), -3, "V");

            var actual = MultiClampDevice.ConvertInput(cmd, data);

            Assert.That(actual, Is.EqualTo(expected));
        }
        public void ShouldUseBackgroundForMode()
        {
            const string VClampUnits = "V";
            const string IClampUnits = "A";

            Measurement VClampBackground = new Measurement(2, -3, VClampUnits);
            Measurement IClampBackground = new Measurement(-10, -3, IClampUnits);

            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var bg = new Dictionary<MultiClampInterop.OperatingMode, IMeasurement>()
                         {
                             {MultiClampInterop.OperatingMode.VClamp, VClampBackground},
                             {MultiClampInterop.OperatingMode.IClamp, IClampBackground},
                         };

            var mcd = new MultiClampDevice(mc, c, bg);
            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            var data = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = MultiClampInterop.OperatingMode.VClamp,
                ExternalCommandSensitivity = 2.5,
                ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.V_V
            };

            mc.FireParametersChanged(DateTimeOffset.Now, data);

            Assert.That(mcd.OutputBackground, Is.EqualTo(MultiClampDevice.ConvertOutput(VClampBackground, mcd.CurrentDeviceOutputParameters.Data)));

            data = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = MultiClampInterop.OperatingMode.IClamp,
                ExternalCommandSensitivity = 1.5,
                ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.A_V
            };

            mc.FireParametersChanged(DateTimeOffset.Now, data);

            Assert.That(mcd.OutputBackground, Is.EqualTo(MultiClampDevice.ConvertOutput(IClampBackground, mcd.CurrentDeviceOutputParameters.Data)));
        }
        public void ShouldRetrieveCurrentDeviceOutputParametersUsingClock()
        {
            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var time = DateTimeOffset.MinValue.Add(MultiClampDevice.ParameterStalenessInterval);

            var clock = Substitute.For<IClock>();
            clock.Now.Returns(time);
            var mcd = new MultiClampDevice(mc, c, UNUSED_BACKGROUND_DICTIONARY) { Clock = clock };

            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            var data = new MultiClampInterop.MulticlampData();
            var expected = new MultiClampInterop.MulticlampData();

            mc.FireParametersChanged(time, data);

            Assert.That(mcd.CurrentDeviceOutputParameters.Data, Is.EqualTo(expected));
        }
        private void BackgroundTest(MultiClampInterop.OperatingMode operatingMode,
            string units,
            MultiClampInterop.ExternalCommandSensitivityUnits extSensUnits)
        {
            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var bg = new Measurement(2, -3, units);

            var background = new Dictionary<MultiClampInterop.OperatingMode, IMeasurement>() { { operatingMode, bg } };
            var mcd = new MultiClampDevice(mc, c, background);
            mcd.BindStream(new DAQOutputStream(UNUSED_NAME));

            var data = new MultiClampInterop.MulticlampData()
                           {
                               OperatingMode = operatingMode,
                               ExternalCommandSensitivity = 2.5,
                               ExternalCommandSensitivityUnits = extSensUnits
                           };

            mc.FireParametersChanged(DateTimeOffset.Now, data);

            var expected = operatingMode == MultiClampInterop.OperatingMode.I0 ?
                new Measurement(0, "V") :
                new Measurement(bg.QuantityInBaseUnit / (decimal)data.ExternalCommandSensitivity, bg.Exponent, "V");

            mc.FireParametersChanged(DateTimeOffset.Now.Subtract(TimeSpan.FromHours(1)), data);

            var actual = mcd.OutputBackground;

            Assert.That(actual, Is.EqualTo(expected));
        }
        public void ShouldNotApplyBackgroundToRunningStreams()
        {
            const string units = "V";
            const MultiClampInterop.OperatingMode vclampMode = MultiClampInterop.OperatingMode.VClamp;

            var c = new Controller();
            var mc = new FakeMulticlampCommander();

            var vclampBackground = new Measurement(2, -3, units);

            var background = new Dictionary<MultiClampInterop.OperatingMode, IMeasurement>()
                                 {
                                     { vclampMode, vclampBackground }
                                 };

            var dataVClamp = new MultiClampInterop.MulticlampData()
            {
                OperatingMode = vclampMode,
                ExternalCommandSensitivity = 2.5,
                ExternalCommandSensitivityUnits = MultiClampInterop.ExternalCommandSensitivityUnits.V_V
            };

            var daq = Substitute.For<IDAQController>();
            var s = new DAQOutputStream("test", daq);

            var mcd = new MultiClampDevice(mc, c, background);
            mcd.BindStream(s);

            daq.IsRunning.Returns(true);

            mc.FireParametersChanged(DateTimeOffset.Now, dataVClamp);

            daq.DidNotReceiveWithAnyArgs().ApplyStreamBackground(s);
        }