示例#1
0
        private void button_computeGain_Click(object sender, EventArgs e)
        {
            double startFreq  = Convert.ToDouble(numericUpDown_startFreq.Value);
            double stopFreq   = Convert.ToDouble(numericUpDown_stopFreq.Value);
            double numPeriods = Convert.ToDouble(numericUpDown_numPeriods.Value);

            double[] freqs = new double[1 + Convert.ToInt32(Math.Floor(Math.Log(stopFreq / startFreq) / Math.Log(Convert.ToDouble(textBox_diagnosticsMult.Text))))]; //This determines the number of frequencies counting by doublings

            radioButton_stimVoltageControlled.Checked = true;
            radioButton_stimVoltageControlled_Click(null, null);

            //Populate freqs vector
            freqs[0] = startFreq;
            for (int i = 1; i < freqs.GetLength(0); ++i)
            {
                freqs[i] = freqs[i - 1] * Convert.ToDouble(textBox_diagnosticsMult.Text);
            }

            spikeSamplingRate          = Properties.Settings.Default.RawSampleFrequency;
            buttonStart.Enabled        = false; //So users can't try to get data from the same card
            button_computeGain.Enabled = false;
            button_computeGain.Refresh();
            buttonStart.Refresh();
            spikeTask          = new List <Task>(Properties.Settings.Default.AnalogInDevice.Count);
            diagnosticsReaders = new List <AnalogMultiChannelReader>(Properties.Settings.Default.AnalogInDevice.Count);
            for (int i = 0; i < Properties.Settings.Default.AnalogInDevice.Count; ++i)
            {
                spikeTask.Add(new Task("spikeTask_Diagnostics_" + i));
                int numChannelsPerDevice = (numChannels < 32 ? numChannels : 32);
                for (int j = 0; j < numChannelsPerDevice; ++j)
                {
                    spikeTask[i].AIChannels.CreateVoltageChannel(Properties.Settings.Default.AnalogInDevice[0] + "/ai" + j.ToString(), "",
                                                                 AITerminalConfiguration.Nrse, -10.0, 10.0, AIVoltageUnits.Volts);
                }

                //Change gain based on comboBox values (1-100)
                setGain(spikeTask[i], Properties.Settings.Default.A2Dgain);

                //Verify the Task
                spikeTask[i].Control(TaskAction.Verify);

                spikeTask[i].Timing.ConfigureSampleClock("", spikeSamplingRate, SampleClockActiveEdge.Rising,
                                                         SampleQuantityMode.FiniteSamples);
                diagnosticsReaders.Add(new AnalogMultiChannelReader(spikeTask[i].Stream));
            }

            spikeTask[0].Timing.ReferenceClockSource = "OnboardClock";
            for (int i = 1; i < spikeTask.Count; ++i)
            {
                spikeTask[i].Timing.ReferenceClockSource = spikeTask[0].Timing.ReferenceClockSource;
                spikeTask[i].Timing.ReferenceClockRate   = spikeTask[0].Timing.ReferenceClockRate;
            }
            stimPulseTask.Timing.ReferenceClockSource = spikeTask[0].Timing.ReferenceClockSource;
            stimPulseTask.Timing.ReferenceClockRate   = spikeTask[0].Timing.ReferenceClockRate;

            stimDigitalTask.Dispose();
            stimDigitalTask = new Task("stimDigitalTask");
            if (Properties.Settings.Default.StimPortBandwidth == 32)
            {
                stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:31", "",
                                                         ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
            }
            else if (Properties.Settings.Default.StimPortBandwidth == 8)
            {
                stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:7", "",
                                                         ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
            }
            stimDigitalWriter = new DigitalSingleChannelWriter(stimDigitalTask.Stream);
            stimPulseTask.Timing.ConfigureSampleClock("/" + Properties.Settings.Default.AnalogInDevice[0] + "/ai/SampleClock",
                                                      spikeSamplingRate, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
            stimPulseTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger("/" +
                                                                            Properties.Settings.Default.AnalogInDevice[0] + "/ai/StartTrigger",
                                                                            DigitalEdgeStartTriggerEdge.Rising);

            stimDigitalTask.Control(TaskAction.Verify);
            stimPulseTask.Control(TaskAction.Verify);

            switch (Properties.Settings.Default.NumChannels)
            {
            case 0:
                numChannels = 16;
                break;

            case 1:
                numChannels = 32;
                break;

            case 2:
                numChannels = 48;
                break;

            case 3:
                numChannels = 64;
                break;
            }
            //gains = new double[numChannels, freqs.GetLength(0)];
            //numChannels = 1;

            gains = new double[numChannels][];
            for (int i = 0; i < numChannels; ++i)
            {
                gains[i] = new double[freqs.GetLength(0)];
            }
            scatterGraph_diagnostics.ClearData();
            scatterGraph_diagnostics.Plots.Clear();

            textBox_diagnosticsResults.Clear();

            if (!checkBox_diagnosticsBulk.Checked)
            {
                //for (int c = 1; c <= numChannels; ++c)
                for (int c = 13; c < 14; ++c)
                {
                    textBox_diagnosticsResults.Text += "Channel " + c.ToString() + "\r\n\tFrequency (Hz)\tGain (dB)\r\n";

                    scatterGraph_diagnostics.Plots.Add(new ScatterPlot());

                    UInt32 data = StimPulse.channel2MUX((double)c); //Get data bits lined up to control MUXes

                    //Setup digital waveform
                    stimDigitalWriter.WriteSingleSamplePort(true, data);
                    stimDigitalTask.WaitUntilDone();
                    stimDigitalTask.Stop();

                    for (int f = 0; f < freqs.GetLength(0); ++f)
                    {
                        double numSeconds = 1 / freqs[f];
                        if (numSeconds * numPeriods < 0.1)
                        {
                            numPeriods = Math.Ceiling(0.1 * freqs[f]);
                        }

                        int        size           = Convert.ToInt32(numSeconds * spikeSamplingRate);
                        SineSignal testWave       = new SineSignal(freqs[f], Convert.ToDouble(numericUpDown_diagnosticsVoltage.Value)); //Generate a 100 mV sine wave at 1000 Hz
                        double[]   testWaveValues = testWave.Generate(spikeSamplingRate, size);

                        double[,] analogPulse = new double[2, size];

                        for (int i = 0; i < size; ++i)
                        {
                            analogPulse[0, i] = testWaveValues[i];
                        }

                        for (int i = 0; i < spikeTask.Count; ++i)
                        {
                            spikeTask[i].Timing.SamplesPerChannel = (long)(numPeriods * size);
                        }

                        stimPulseTask.Timing.SamplesPerChannel = (long)(numPeriods * size); //Do numperiods cycles of sine wave
                        stimPulseWriter.WriteMultiSample(true, analogPulse);

                        double[] stateData = new double[4];
                        stateData[0] = (double)c;
                        stateData[1] = freqs[f];
                        stateData[2] = (double)f;
                        for (int i = diagnosticsReaders.Count - 1; i >= 0; --i)
                        {
                            stateData[3] = (double)i;
                            diagnosticsReaders[i].BeginReadMultiSample((int)(numPeriods * size), analogInCallback_computeGain, (Object)stateData); //Get 5 seconds of "noise"
                        }

                        stimPulseTask.WaitUntilDone();
                        for (int i = 0; i < spikeTask.Count; ++i)
                        {
                            spikeTask[i].WaitUntilDone();
                            spikeTask[i].Stop();
                        }
                        stimPulseTask.Stop();
                    }
                    stimDigitalWriter.WriteSingleSamplePort(true, 0);
                    stimDigitalTask.WaitUntilDone();
                    stimDigitalTask.Stop();
                    //DEBUGGING
                    c = 1;
                    scatterGraph_diagnostics.Plots[c - 1].PlotXY(freqs, gains[c - 1]);
                    for (int f = 0; f < freqs.GetLength(0); ++f)
                    {
                        textBox_diagnosticsResults.Text += "\t" + freqs[f].ToString() + "\t" + gains[c - 1][f] + "\r\n";
                    }
                    textBox_diagnosticsResults.Text += "\r\n";
                    scatterGraph_diagnostics.Refresh();

                    //DEBUGGING
                    c = 100;
                }
            }
            else
            {
                for (int f = 0; f < freqs.GetLength(0); ++f)
                {
                    double numSeconds = 1 / freqs[f];
                    if (numSeconds * numPeriods < 0.1)
                    {
                        numPeriods = Math.Ceiling(0.1 * freqs[f]);
                    }

                    int        size           = Convert.ToInt32(numSeconds * spikeSamplingRate);
                    SineSignal testWave       = new SineSignal(freqs[f], Convert.ToDouble(numericUpDown_diagnosticsVoltage.Value)); //Generate a 100 mV sine wave at 1000 Hz
                    double[]   testWaveValues = testWave.Generate(spikeSamplingRate, size);


                    double[,] analogPulse = new double[2, size];

                    for (int i = 0; i < size; ++i)
                    {
                        analogPulse[0, i] = testWaveValues[i];
                    }

                    for (int i = 0; i < spikeTask.Count; ++i)
                    {
                        spikeTask[i].Timing.SamplesPerChannel = (long)(numPeriods * size);
                    }

                    stimPulseTask.Timing.SamplesPerChannel = (long)(numPeriods * size); //Do numperiods cycles of sine wave
                    stimPulseWriter.WriteMultiSample(true, analogPulse);

                    double[] stateData = new double[4];
                    stateData[0] = -1.0;
                    stateData[1] = freqs[f];
                    stateData[2] = (double)f; //Frequency of interest

                    for (int i = diagnosticsReaders.Count - 1; i >= 0; --i)
                    {
                        stateData[3] = (double)i;                                                                                              //Keeps track of which device called the reader
                        diagnosticsReaders[i].BeginReadMultiSample((int)(numPeriods * size), analogInCallback_computeGain, (Object)stateData); //Get 5 seconds of "noise"
                    }

                    stimPulseTask.WaitUntilDone();
                    for (int i = 0; i < spikeTask.Count; ++i)
                    {
                        spikeTask[i].WaitUntilDone();
                        spikeTask[i].Stop();
                    }
                    stimPulseTask.Stop();
                }
                for (int c = 0; c < numChannels; ++c)
                {
                    scatterGraph_diagnostics.Plots.Add(new ScatterPlot());
                    scatterGraph_diagnostics.Plots[c].PlotXY(freqs, gains[c]);
                    textBox_diagnosticsResults.Text += "Channel " + (c + 1).ToString() + "\r\n\tFrequency (Hz)\tGain (dB)\r\n";
                    for (int f = 0; f < freqs.GetLength(0); ++f)
                    {
                        textBox_diagnosticsResults.Text += "\t" + freqs[f].ToString() + "\t" + gains[c][f].ToString() + "\r\n";
                    }
                    textBox_diagnosticsResults.Text += "\r\n";
                }
                scatterGraph_diagnostics.Refresh();
            }
            buttonStart.Enabled        = true;
            button_computeGain.Enabled = true;

            //Now, destroy the objects we made
            updateSettings();
            gains = null;
            diagnosticsReaders = null;
        }
示例#2
0
        private void button_electrolesioningStart_Click(object sender, EventArgs e)
        {
            //Change mouse cursor to waiting cursor
            this.Cursor = Cursors.WaitCursor;

            //Grab values from UI
            double       voltage  = Convert.ToDouble(numericUpDown_electrolesioningVoltage.Value);
            double       duration = Convert.ToDouble(numericUpDown_electrolesioningDuration.Value);
            List <Int32> chList   = new List <int>(listBox_electrolesioningChannels.SelectedIndices.Count);

            for (int i = 0; i < listBox_electrolesioningChannels.SelectedIndices.Count; ++i)
            {
                chList.Add(listBox_electrolesioningChannels.SelectedIndices[i] + 1); //+1 since indices are 0-based but channels are 1-base
            }
            //Disable buttons, so users don't try running two experiments at once
            button_electrolesioningStart.Enabled      = false;
            button_electrolesioningSelectAll.Enabled  = false;
            button_electrolesioningSelectNone.Enabled = false;
            button_electrolesioningStart.Refresh();

            //Refresh stim task
            stimDigitalTask.Dispose();
            stimDigitalTask = new Task("stimDigitalTask_Electrolesioning");
            if (Properties.Settings.Default.StimPortBandwidth == 32)
            {
                stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:31", "",
                                                         ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
            }
            else if (Properties.Settings.Default.StimPortBandwidth == 8)
            {
                stimDigitalTask.DOChannels.CreateChannel(Properties.Settings.Default.StimulatorDevice + "/Port0/line0:7", "",
                                                         ChannelLineGrouping.OneChannelForAllLines); //To control MUXes
            }
            stimDigitalWriter = new DigitalSingleChannelWriter(stimDigitalTask.Stream);

            //Refresh pulse task
            stimPulseTask.Dispose();
            stimPulseTask = new Task("stimPulseTask");
            if (Properties.Settings.Default.StimPortBandwidth == 32)
            {
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao0", "", -10.0, 10.0, AOVoltageUnits.Volts); //Triggers
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao1", "", -10.0, 10.0, AOVoltageUnits.Volts); //Triggers
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao2", "", -10.0, 10.0, AOVoltageUnits.Volts); //Actual Pulse
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao3", "", -10.0, 10.0, AOVoltageUnits.Volts); //Timing
            }
            else if (Properties.Settings.Default.StimPortBandwidth == 8)
            {
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao0", "", -10.0, 10.0, AOVoltageUnits.Volts);
                stimPulseTask.AOChannels.CreateVoltageChannel(Properties.Settings.Default.StimulatorDevice + "/ao1", "", -10.0, 10.0, AOVoltageUnits.Volts);
            }

            stimPulseWriter = new AnalogMultiChannelWriter(stimPulseTask.Stream);

            stimPulseTask.Timing.ConfigureSampleClock("",
                                                      StimPulse.STIM_SAMPLING_FREQ, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples);
            stimPulseTask.Timing.SamplesPerChannel = 2;


            stimDigitalTask.Control(TaskAction.Verify);
            stimPulseTask.Control(TaskAction.Verify);

            //For each channel, deliver lesioning pulse
            for (int i = 0; i < chList.Count; ++i)
            {
                int    channel = chList[i];
                UInt32 data    = StimPulse.channel2MUX((double)channel);

                //Setup digital waveform, open MUX channel
                stimDigitalWriter.WriteSingleSamplePort(true, data);
                stimDigitalTask.WaitUntilDone();
                stimDigitalTask.Stop();

                //Write voltage to channel, wait duration, stop
                stimPulseWriter.WriteMultiSample(true, new double[, ] {
                    { 0, 0 }, { 0, 0 }, { voltage, voltage }, { 0, 0 }
                });
                stimPulseTask.WaitUntilDone();
                stimPulseTask.Stop();
                Thread.Sleep((int)(Math.Round(duration * 1000))); //Convert to ms
                stimPulseWriter.WriteMultiSample(true, new double[, ] {
                    { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }
                });
                stimPulseTask.WaitUntilDone();
                stimPulseTask.Stop();

                //Close MUX
                stimDigitalWriter.WriteSingleSamplePort(true, 0);
                stimDigitalTask.WaitUntilDone();
                stimDigitalTask.Stop();
            }

            bool[] fData = new bool[Properties.Settings.Default.StimPortBandwidth];
            stimDigitalWriter.WriteSingleSampleMultiLine(true, fData);
            stimDigitalTask.WaitUntilDone();
            stimDigitalTask.Stop();

            button_electrolesioningSelectAll.Enabled  = true;
            button_electrolesioningSelectNone.Enabled = true;
            button_electrolesioningStart.Enabled      = true;

            //Now, destroy the objects we made
            updateSettings();
            this.Cursor = Cursors.Default;
        }
示例#3
0
        void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            //Measure each channel
            for (int c = 0; c < numChannels && !bgWorker.CancellationPending; ++c)
            {
                UInt32 MuxData = StimPulse.channel2MUX(Convert.ToDouble(startChannel + c));

                //Setup digital waveform, open MUX channel
                stimDigitalWriter.WriteSingleSamplePort(true, MuxData);
                stimDigitalTask.WaitUntilDone();
                stimDigitalTask.Stop();

                double numPeriodsUsed = numPeriods;
                for (int f = 0; f < freqs.GetLength(0) && !bgWorker.CancellationPending; ++f)
                {
                    //Update progress bars
                    bgWorker.ReportProgress(100 * (f + (c * freqs.Length)) / (numChannels * freqs.Length), new double[] { startChannel + c, freqs[f] });

                    //Create test wave
                    double numSeconds = 1 / freqs[f];
                    if (numSeconds * numPeriods < 0.1)
                    {
                        numPeriodsUsed = Math.Ceiling(0.1 * freqs[f]);
                    }
                    SineSignal testWave       = new SineSignal(freqs[f], commandVoltage); //Generate a 100 mV sine wave at 1000 Hz
                    double[]   testWaveValues = testWave.Generate(IMPEDANCE_SAMPLING_RATE, (long)Math.Round(numSeconds * (double)IMPEDANCE_SAMPLING_RATE));

                    int size = Convert.ToInt32(numSeconds * IMPEDANCE_SAMPLING_RATE);
                    double[,] analogPulse = new double[4, size];

                    for (int i = 0; i < size; ++i)
                    {
                        analogPulse[0 + 2, i] = testWaveValues[i];
                    }

                    impedanceRecord.Timing.SamplesPerChannel = (long)(numPeriodsUsed * size);
                    stimAnalogTask.Timing.SamplesPerChannel  = (long)(numPeriodsUsed * size); //Do numperiods cycles of sine wave

                    //Deliver pulse
                    stimAnalogWriter.WriteMultiSample(true, analogPulse);
                    double[] data = impedanceReader.ReadMultiSample((int)(numPeriodsUsed * size));

                    #region Calculate Impedance
                    //Remove DC offset
                    double mData = 0.0;
                    for (int i = 0; i < data.Length; ++i)
                    {
                        mData += data[i];
                    }
                    mData /= data.Length;
                    for (int i = 0; i < data.Length; ++i)
                    {
                        data[i] -= mData;
                    }

                    //Filter data with Butterworth, if checked
                    if (useBandpassFilter)
                    {
                        ButterworthBandpassFilter bwfilt = new ButterworthBandpassFilter(1, IMPEDANCE_SAMPLING_RATE, freqs[f] - freqs[f] / 4, freqs[f] + freqs[f] / 4);
                        data = bwfilt.FilterData(data);
                    }

                    //Use matched filter to reduce noise, if checked (slow)
                    if (useMatchedFilter)
                    {
                        SineSignal wave = new SineSignal(freqs[f], 1.0); //Create a sine wave at test frequency of amplitude 1
                        double[]   h;                                    //filter
                        //If data is very long, subsample by an order of magnitude
                        if (data.Length > 1E6)
                        {
                            double[] dataNew = new double[(int)Math.Floor((double)data.Length / 10)];
                            for (int i = 0; i < dataNew.Length; ++i)
                            {
                                dataNew[i] = data[i * 10];
                            }
                            data    = dataNew;
                            dataNew = null;
                            h       = wave.Generate(IMPEDANCE_SAMPLING_RATE / 10, (long)Math.Round((double)IMPEDANCE_SAMPLING_RATE / (freqs[f] * 10))); //Generate one period
                        }

                        else
                        {
                            h = wave.Generate(IMPEDANCE_SAMPLING_RATE, (long)Math.Round((double)IMPEDANCE_SAMPLING_RATE / freqs[f])); //Generate one period
                        }
                        wave = null;
                        //Compute filter power
                        double phh = 0.0;
                        for (int i = 0; i < h.Length; ++i)
                        {
                            phh += h[i] * h[i];
                        }
                        //Normalize filter so power is 1
                        for (int i = 0; i < h.Length; ++i)
                        {
                            h[i] /= phh;
                        }

                        //sw.Start();
                        double[] x = NationalInstruments.Analysis.Dsp.SignalProcessing.Convolve(data, h);
                        //sw.Stop();
                        //TimeSpan ts = sw.Elapsed;
                        //System.Diagnostics.Debug.WriteLine("ms = " + ts.Milliseconds + "\t s = " + ts.Seconds + "\t min = " + ts.Minutes);

                        int offset = (int)(h.Length * 0.5);
                        for (int i = 0; i < data.Length; ++i)
                        {
                            data[i] = x[i + offset];                                   //Take center values
                        }
                    }

                    double rms = rootMeanSquared(data);

                    if (isCurrentControlled)  //Current-controlled
                    {
                        impedance[c][f] = rms / (0.707106704695506 * commandVoltage / RCurr);
                        //Account for 6.8 MOhm resistor in parallel
                        impedance[c][f] = 1.0 / (1.0 / impedance[c][f] - 1.0 / 6800000.0);
                    }
                    else  //Voltage-controlled
                    {
                        double gain = 1.0 + (49400.0 / RGain); //Based on LT in-amp
                        impedance[c][f] = (0.707106704695506 * commandVoltage) / ((rms / gain) / RMeas);
                    }
                    #endregion

                    //Wait until recording and stim are finished
                    stimAnalogTask.WaitUntilDone();
                    impedanceRecord.WaitUntilDone();
                    stimAnalogTask.Stop();
                    impedanceRecord.Stop();
                }

                //De-select channel on mux
                stimDigitalWriter.WriteSingleSamplePort(true, 0);
                stimDigitalTask.WaitUntilDone();
                stimDigitalTask.Stop();

                //Notify that channel is done
                if (alertChannelFinished != null)
                {
                    alertChannelFinished(this, c, startChannel + c, impedance, freqs);
                }
            }
            //Reset muxes
            bool[] fData = new bool[Properties.Settings.Default.StimPortBandwidth];
            stimDigitalWriter.WriteSingleSampleMultiLine(true, fData);
            stimDigitalTask.WaitUntilDone();
            stimDigitalTask.Stop();
        }