public void FireParametersChanged(DateTimeOffset time, MultiClampInterop.MulticlampData data)
        {
            var clock = new FakeClock(time);
            var args  = new MultiClampParametersChangedArgs(clock, data);

            ParametersChanged(this, args);
        }
        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 ShouldSetExternalCommandSensitivityUnits(
            [Values((UInt32)0, (UInt32)1, (UInt32)2)] UInt32 operatingMode
            )
        {
            var data = new MultiClampInterop.MC_TELEGRAPH_DATA()
            {
                uOperatingMode = operatingMode
            };

            var mcd = new MultiClampInterop.MulticlampData(data);

            switch (mcd.OperatingMode)
            {
            case MultiClampInterop.OperatingMode.VClamp:
                Assert.That(mcd.ExternalCommandSensitivityUnits, Is.EqualTo(MultiClampInterop.ExternalCommandSensitivityUnits.V_V));
                break;

            case MultiClampInterop.OperatingMode.IClamp:
                Assert.That(mcd.ExternalCommandSensitivityUnits, Is.EqualTo(MultiClampInterop.ExternalCommandSensitivityUnits.A_V));

                break;

            case MultiClampInterop.OperatingMode.I0:
                Assert.That(mcd.ExternalCommandSensitivityUnits, Is.EqualTo(MultiClampInterop.ExternalCommandSensitivityUnits.OFF));
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
예제 #5
0
 private static void CheckScaleFactorUnits(MultiClampInterop.MulticlampData deviceParams, MultiClampInterop.ScaleFactorUnits[] allowedScaleFactorUnits)
 {
     if (!allowedScaleFactorUnits.Contains(deviceParams.ScaleFactorUnits))
     {
         throw new MultiClampDeviceException(deviceParams.ScaleFactorUnits + " is not an allowed unit conversion for scaled output mode.");
     }
 }
        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));
        }
예제 #7
0
        public static Measurement ConvertOutput(IMeasurement sample, MultiClampInterop.MulticlampData deviceParams)
        {
            switch (deviceParams.OperatingMode)
            {
            //Output cmd in Volts
            case MultiClampInterop.OperatingMode.VClamp:

                if (string.Compare(sample.BaseUnit, "V", false) != 0)     //output
                {
                    throw new ArgumentException("Sample units must be in Volts.", "sample.BaseUnit");
                }

                if (deviceParams.ExternalCommandSensitivityUnits != MultiClampInterop.ExternalCommandSensitivityUnits.V_V)
                {
                    throw new MultiClampDeviceException("External command units are not V/V as expected for current deivce mode.");
                }

                break;

            //Output cmd in amps
            case MultiClampInterop.OperatingMode.IClamp:
                if (deviceParams.ExternalCommandSensitivityUnits != MultiClampInterop.ExternalCommandSensitivityUnits.A_V)
                {
                    log.ErrorFormat("External Command Sensitivity Units " + deviceParams.ExternalCommandSensitivityUnits + " do not match expected (" + MultiClampInterop.ExternalCommandSensitivityUnits.A_V + ")");
                    throw new MultiClampDeviceException("External command units " + deviceParams.ExternalCommandSensitivityUnits + " are not A/V as expected for current deivce mode.");
                }


                if (string.Compare(sample.BaseUnit, "A", false) != 0)     //output
                {
                    throw new ArgumentException("Sample units must be in Amps.", "sample.BaseUnit");
                }

                break;

            case MultiClampInterop.OperatingMode.I0:
                if (!(deviceParams.ExternalCommandSensitivityUnits == MultiClampInterop.ExternalCommandSensitivityUnits.A_V ||
                      deviceParams.ExternalCommandSensitivityUnits == MultiClampInterop.ExternalCommandSensitivityUnits.OFF))
                {
                    log.ErrorFormat("External Command Sensitivity Units " + deviceParams.ExternalCommandSensitivityUnits + " do not match expected (" + MultiClampInterop.ExternalCommandSensitivityUnits.A_V + ")");
                    throw new MultiClampDeviceException("External command units " + deviceParams.ExternalCommandSensitivityUnits + " are not A/V as expected for current deivce mode.");
                }

                if (string.Compare(sample.BaseUnit, "A", false) != 0)     //output
                {
                    throw new ArgumentException("Sample units must be in Amps.", "sample.BaseUnit");
                }

                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            return(deviceParams.OperatingMode == MultiClampInterop.OperatingMode.I0 ?
                   new Measurement(0, "V") :
                   new Measurement(sample.QuantityInBaseUnit / (decimal)deviceParams.ExternalCommandSensitivity, sample.Exponent, "V"));
        }
예제 #8
0
 private void OnParametersChanged(MultiClampInterop.MulticlampData data)
 {
     lock (_eventLock)
     {
         if (ParametersChanged != null)
         {
             ParametersChanged(this, new MultiClampParametersChangedArgs(Clock, data));
         }
     }
 }
예제 #9
0
        private void RegisterForWmCopyDataEvents()
        {
            log.Debug("Registering from WM_COPYDATA messages");

            Win32Interop.MessageEvents.WatchMessage(Win32Interop.WM_COPYDATA, (sender, evtArgs) =>
            {
                // WM_COPYDATA LPARAM is a pointer to a COPYDATASTRUCT structure
                Win32Interop.COPYDATASTRUCT cds;
                cds = (Win32Interop.COPYDATASTRUCT)
                      Marshal.PtrToStructure(
                    evtArgs.Message.LParam,
                    typeof(
                        Win32Interop.COPYDATASTRUCT));

                // WM_COPYDATA structure (COPYDATASTRUCT)
                // dwData -- RegisterWindowMessage(MCTG_REQUEST_MESSAGE_STR)
                // cbData -- size (in bytes) of the MC_TELEGRAPH_DATA structure being sent
                // lpData -- MC_TELEGRAPH_DATA*
                try
                {
                    if (cds.lpData != IntPtr.Zero)
                    {
                        MultiClampInterop.
                        MC_TELEGRAPH_DATA mtd
                            =
                                (
                                    MultiClampInterop.
                                    MC_TELEGRAPH_DATA
                                )
                                Marshal.
                                PtrToStructure
                                    (cds.lpData,
                                    typeof(
                                        MultiClampInterop
                                        .
                                        MC_TELEGRAPH_DATA
                                        ));
                        var md =
                            new MultiClampInterop.
                            MulticlampData(
                                mtd);

                        log.Debug(
                            "WM_COPYDATA message recieved from MCCommander");
                        OnParametersChanged(md);
                    }
                }
                catch (ArgumentOutOfRangeException)
                {
                    log.ErrorFormat("WM_COPYDATA message received from MCCommander, but operating mode is not valid.");
                    RequestTelegraphValue((uint)evtArgs.Message.LParam);
                }
            });
        }
        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.");
        }
예제 #11
0
        private static Measurement ConvertInputMeasurement(IMeasurement sample, MultiClampInterop.MulticlampData deviceParams)
        {
            var desiredUnitsMultiplier = (decimal)Math.Pow(10,
                                                           (ExponentForScaleFactorUnits(deviceParams.ScaleFactorUnits) -
                                                            DesiredUnitsExponentForScaleFactorUnits(
                                                                deviceParams.ScaleFactorUnits))
                                                           );

            return
                (new Measurement(
                     (sample.QuantityInBaseUnit / (decimal)deviceParams.ScaleFactor / (decimal)deviceParams.Alpha) *
                     desiredUnitsMultiplier,
                     DesiredUnitsExponentForScaleFactorUnits(deviceParams.ScaleFactorUnits),
                     UnitsForScaleFactorUnits(deviceParams.ScaleFactorUnits)));
        }
예제 #12
0
        public static Measurement ConvertInput(IMeasurement sample, MultiClampInterop.MulticlampData deviceParams)
        {
            switch (deviceParams.OperatingMode)
            {
            case MultiClampInterop.OperatingMode.VClamp:
                return(ConvertVClampInput(sample, deviceParams));

            case MultiClampInterop.OperatingMode.IClamp:
            case MultiClampInterop.OperatingMode.I0:
                return(ConvertIClampInput(sample, deviceParams));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
        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 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 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));
        }
예제 #16
0
        private static Measurement ConvertIClampInput(IMeasurement sample, MultiClampInterop.MulticlampData deviceParams)
        {
            //MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_I_CMD_MEMB,
            //              MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_I_CMD_SUMMED
            switch (deviceParams.ScaledOutputSignal)
            {
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_I_CMD_MEMB:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_I_CMD_SUMMED:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_SEC_IC_GLDR_I_CMD_MEMB:
                CheckScaleFactorUnits(deviceParams, new[] {
                    MultiClampInterop.ScaleFactorUnits.V_A,
                    MultiClampInterop.ScaleFactorUnits.V_mA,
                    MultiClampInterop.ScaleFactorUnits.V_nA,
                    MultiClampInterop.ScaleFactorUnits.V_uA,
                    MultiClampInterop.ScaleFactorUnits.V_pA
                });

                break;

            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_MIN:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_MAX:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_V_MEMBx100:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_I_CMD_EXT:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_PRI_IC_GLDR_AUX1:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_SEC_IC_GLDR_MIN:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_SEC_IC_GLDR_MAX:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_SEC_IC_GLDR_V_MEMB:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_SEC_IC_GLDR_V_MEMBx100:
            case MultiClampInterop.SignalIdentifier.AXMCD_OUT_SEC_IC_GLDR_I_CMD_EXT:
                CheckScaleFactorUnits(deviceParams, new[] {
                    MultiClampInterop.ScaleFactorUnits.V_mV,
                    MultiClampInterop.ScaleFactorUnits.V_uV,
                    MultiClampInterop.ScaleFactorUnits.V_V
                });
                break;

            default:
                log.ErrorFormat("MultiClamp scaled output signal is not a valid IClamp mode: {0}", deviceParams.ScaledOutputSignal);
                throw new ArgumentOutOfRangeException();
            }

            return(ConvertInputMeasurement(sample, deviceParams));
        }
        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 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 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));
        }
예제 #21
0
        private static IDictionary <string, object> MergeDeviceParametersIntoConfiguration(IDictionary <string, object> config,
                                                                                           MultiClampInterop.MulticlampData deviceParameters)
        {
            var result = config == null ?
                         new Dictionary <string, object>() :
                         new Dictionary <string, object>(config);

            result["Alpha"]      = deviceParameters.Alpha;
            result["AppVersion"] = deviceParameters.AppVersion;
            result["DSPVersion"] = deviceParameters.DSPVersion;
            result["ExternalCommandSensitivity"]      = deviceParameters.ExternalCommandSensitivity;
            result["ExternalCommandSensitivityUnits"] = deviceParameters.ExternalCommandSensitivityUnits.ToString();
            result["FirmwareVersion"]     = deviceParameters.FirmwareVersion;
            result["HardwareType"]        = deviceParameters.HardwareType.ToString();
            result["LPFCutoff"]           = deviceParameters.LPFCutoff;
            result["MembraneCapacitance"] = deviceParameters.MembraneCapacitance;
            result["OperatingMode"]       = deviceParameters.OperatingMode.ToString();
            result["RawOutputSignal"]     = deviceParameters.RawOutputSignal.ToString();
            result["RawScaleFactor"]      = deviceParameters.RawScaleFactor;
            result["RawScaleFactorUnits"] = deviceParameters.RawScaleFactorUnits.ToString();
            result["ScaledOutputSignal"]  = deviceParameters.ScaledOutputSignal.ToString();
            result["ScaleFactor"]         = deviceParameters.ScaleFactor;
            result["ScaleFactorUnits"]    = deviceParameters.ScaleFactorUnits.ToString();
            result["SecondaryAlpha"]      = deviceParameters.SecondaryAlpha;
            result["SecondaryLPFCutoff"]  = deviceParameters.SecondaryLPFCutoff;
            result["SerialNumber"]        = deviceParameters.SerialNumber;

            return(result);
        }
예제 #22
0
        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));
        }
예제 #23
0
        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)));
        }
예제 #24
0
        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.");
        }
예제 #25
0
        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));
        }
예제 #26
0
        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));
        }
        private void ReceiveWmCopyDataEvent(object sender, Win32Interop.MessageReceivedEventArgs evtArgs)
        {
            // WM_COPYDATA LPARAM is a pointer to a COPYDATASTRUCT structure
            Win32Interop.COPYDATASTRUCT cds = (Win32Interop.COPYDATASTRUCT) Marshal.PtrToStructure(evtArgs.Message.LParam, typeof (Win32Interop.COPYDATASTRUCT));

            // WM_COPYDATA structure (COPYDATASTRUCT)
            // dwData -- RegisterWindowMessage(MCTG_REQUEST_MESSAGE_STR)
            // cbData -- size (in bytes) of the MC_TELEGRAPH_DATA structure being sent
            // lpData -- MC_TELEGRAPH_DATA*
            try
            {
                if (cds.lpData == IntPtr.Zero || (cds.cbData != 128 /* 700A */ && cds.cbData != 256 /* 700B */) || (long)cds.dwData != MultiClampInterop.MCTG_REQUEST_MESSAGE)
                    return;

                var mtd = (MultiClampInterop.MC_TELEGRAPH_DATA)Marshal.PtrToStructure(cds.lpData, typeof(MultiClampInterop.MC_TELEGRAPH_DATA));
                if (mtd.uChannelID != Channel)
                    return;

                // For some reason the hardware type can come through corrupted. The rest of the structure is intact however.
                if (mtd.uHardwareType != (uint)MultiClampInterop.HardwareType.MCTG_HW_TYPE_MC700A && mtd.uHardwareType != (uint)MultiClampInterop.HardwareType.MCTG_HW_TYPE_MC700B)
                {
                    log.Debug("Unknown hardware type in received message. Using device hardware type instead.");
                    mtd.uHardwareType = (uint)HardwareType;
                }
                if (mtd.uHardwareType != (uint)HardwareType)
                    return;

                var md = new MultiClampInterop.MulticlampData(mtd);

                log.Debug("WM_COPYDATA message received from MCCommander");
                OnParametersChanged(md);
            }
            catch (ArgumentOutOfRangeException)
            {
                log.ErrorFormat("WM_COPYDATA message received from MCCommander, but operating mode is not valid.");
                RequestTelegraphValue((uint) evtArgs.Message.LParam);
            }
        }
예제 #28
0
        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));
        }
예제 #29
0
        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();
        }
예제 #30
0
        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 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));
        }
예제 #32
0
        public void ShouldConvertInputUnitsInVClamp(
            [Values(MultiClampInterop.OperatingMode.VClamp)] MultiClampInterop.OperatingMode operatingMode,
            [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(1, 2, 10)] double alpha
            )
        {
            var data = new MultiClampInterop.MulticlampData()
                           {
                               OperatingMode = operatingMode,
                               ScaleFactor = 2.5,
                               ScaleFactorUnits = scaleFactorUnits,
                               ScaledOutputSignal = MultiClampInterop.SignalIdentifier.AXMCD_OUT_SEC_VC_GLDR_I_MEMB,
                               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), -12, "A");

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

            Assert.That(actual, Is.EqualTo(expected));
        }
        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));
        }
예제 #34
0
        public void ShouldSetExternalCommandSensitivityUnits(
            [Values((UInt32)0, (UInt32)1, (UInt32)2)] UInt32 operatingMode
            )
        {
            var data = new MultiClampInterop.MC_TELEGRAPH_DATA()
                           {
                               uOperatingMode = operatingMode
                           };

            var mcd = new MultiClampInterop.MulticlampData(data);
            switch (mcd.OperatingMode)
            {
                case MultiClampInterop.OperatingMode.VClamp:
                    Assert.That(mcd.ExternalCommandSensitivityUnits, Is.EqualTo(MultiClampInterop.ExternalCommandSensitivityUnits.V_V));
                    break;
                case MultiClampInterop.OperatingMode.IClamp:
                    Assert.That(mcd.ExternalCommandSensitivityUnits, Is.EqualTo(MultiClampInterop.ExternalCommandSensitivityUnits.A_V));

                    break;
                case MultiClampInterop.OperatingMode.I0:
                    Assert.That(mcd.ExternalCommandSensitivityUnits, Is.EqualTo(MultiClampInterop.ExternalCommandSensitivityUnits.OFF));
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
예제 #35
0
        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));
        }
예제 #36
0
 public MultiClampParametersChangedArgs(IClock clock, MultiClampInterop.MulticlampData data)
     : base(clock)
 {
     this.Data = data;
 }
예제 #37
0
        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));
        }
예제 #38
0
        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));
        }
예제 #39
0
        private void RegisterForWmCopyDataEvents()
        {
            log.Debug("Registering from WM_COPYDATA messages");

            Win32Interop.MessageEvents.WatchMessage(Win32Interop.WM_COPYDATA, (sender, evtArgs) =>
                                                                                  {
                                                                                      // WM_COPYDATA LPARAM is a pointer to a COPYDATASTRUCT structure
                                                                                      Win32Interop.COPYDATASTRUCT cds;
                                                                                      cds = (Win32Interop.COPYDATASTRUCT)
                                                                                            Marshal.PtrToStructure(
                                                                                                evtArgs.Message.LParam,
                                                                                                typeof(
                                                                                                    Win32Interop.COPYDATASTRUCT));

                                                                                      // WM_COPYDATA structure (COPYDATASTRUCT)
                                                                                      // dwData -- RegisterWindowMessage(MCTG_REQUEST_MESSAGE_STR)
                                                                                      // cbData -- size (in bytes) of the MC_TELEGRAPH_DATA structure being sent
                                                                                      // lpData -- MC_TELEGRAPH_DATA*
                                                                                      try
                                                                                      {
                                                                                          if (cds.lpData != IntPtr.Zero)
                                                                                          {
                                                                                              MultiClampInterop.
                                                                                                  MC_TELEGRAPH_DATA mtd
                                                                                                      =
                                                                                                      (
                                                                                                      MultiClampInterop.
                                                                                                          MC_TELEGRAPH_DATA
                                                                                                      )
                                                                                                      Marshal.
                                                                                                          PtrToStructure
                                                                                                          (cds.lpData,
                                                                                                           typeof (
                                                                                                               MultiClampInterop
                                                                                                               .
                                                                                                               MC_TELEGRAPH_DATA
                                                                                                               ));
                                                                                              var md =
                                                                                                  new MultiClampInterop.
                                                                                                      MulticlampData(
                                                                                                      mtd);

                                                                                              log.Debug(
                                                                                                  "WM_COPYDATA message recieved from MCCommander");
                                                                                              OnParametersChanged(md);
                                                                                          }
                                                                                      }
                                                                                      catch (ArgumentOutOfRangeException)
                                                                                      {
                                                                                          log.ErrorFormat("WM_COPYDATA message received from MCCommander, but operating mode is not valid.");
                                                                                          RequestTelegraphValue((uint)evtArgs.Message.LParam);
                                                                                      }
                                                                                  });
        }
        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);
        }