private void AnalogInCallback(IAsyncResult ar)
        {
            try
            {
                if (runningTask != null && runningTask == ar.AsyncState)
                {
                    // Read the available data from the channels
                    data = analogInReader.EndReadWaveform(ar);

                    double[] values = data[0].GetRawData(0, data[0].SampleCount);

                    waveformGraphScope.Plots[0].PlotWaveformAppend(data[0]);

                    analogInReader.BeginMemoryOptimizedReadWaveform(Convert.ToInt32(sampleRate),
                        analogCallback, myTask, data);

                }
            }
            catch (DaqException exception)
            {
                // Display Errors
                MessageBox.Show(exception.Message);
                runningTask = null;
                myTask.Dispose();
            }
        }
Example #2
0
        /// <summary>
        /// 采集到N个样本的事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AiEveryNSamplesRead(object sender, EveryNSamplesReadEventArgs e)
        {
            try
            {
                // 读取16位原始数据,每次读取单次采集的像素数
                int channelNum = m_config.GetChannelNum();
                short[,] originSamples = m_aiUnscaledReader.ReadInt16(m_params.ScanPixelsPerAcquisition);
                AnalogWaveform <short>[] waves = AnalogWaveform <short> .FromArray2D(originSamples);

                short[][] samples = new short[channelNum][];
                for (int i = 0; i < channelNum; i++)
                {
                    samples[i] = m_params.GetLaserAiChannelIndex(i) >= 0 ? waves[m_params.GetLaserAiChannelIndex(i)].GetRawData() : null;
                }

                if (AiSamplesReceived != null)
                {
                    AiSamplesReceived.Invoke(this, samples);
                }
            }
            catch (Exception err)
            {
                Logger.Error(string.Format("every n samples read exception: [{0}].", err));
            }
        }
Example #3
0
        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                button4.Enabled = false;
                NationalInstruments.AnalogWaveform <double>[] generatedData = new NationalInstruments.AnalogWaveform <double> [anlog_OutputComponent1.NumberOfChannelsToWrite];

                // TODO: Populate data to write.
                //throw new System.NotImplementedException("You must populate the data to write before writing the data.");

                int numberOfPoints = 100;
                AnalogWaveform <double> analogWaveform = new AnalogWaveform <double>(numberOfPoints);

                for (int i = 0; i < numberOfPoints; i++)
                {
                    analogWaveform.Samples[i].Value = 3;
                }

                generatedData[0] = analogWaveform;
                generatedData[1] = analogWaveform;


                anlog_OutputComponent1.WriteAsync(generatedData);
                waveformGraph2.PlotWaveforms(generatedData);
            }
            catch (NationalInstruments.DAQmx.DaqException ex)
            {
                MessageBox.Show(ex.Message, "DAQ Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                button4.Enabled = true;
            }
        }
        private void myCallback(IAsyncResult ar)
        {
            try
            {
                if (runningTask != null && runningTask == ar.AsyncState)
                {
                    data = reader.EndReadWaveform(ar);

                    //Acquire Data
                    for (int i = 0; i < data.SampleCount; i++)
                    {
                        double d = data.Samples[i].Value;
                    }

                    // Continue to acquire if task still running
                    reader.BeginMemoryOptimizedReadWaveform(samplesPerChannel, new AsyncCallback(myCallback), myTask, data);
                }
            }
            catch (DaqException ex)
            {
                MessageBox.Show(ex.Message);
                runningTask = null;
                myTask.Dispose();
            }
        }
Example #5
0
        public int ReadWaveformAnalogChannel(string lines, string name, AITerminalConfiguration config, ref AnalogWaveform <double>[] channelData, double min, double max, int nsamples)
        {
            //Create a task such that it will be disposed after
            //we are done using it.
            Task      analogReadTask = new Task();
            AIChannel ch             = null;

            AnalogWaveform <double>[] channelData2 = new AnalogWaveform <double> [analogReadTask.AIChannels.Count];

            if (max == 0)
            {
                max = 10;
            }
            if (nsamples == 0)
            {
                nsamples = -1;
            }

            try
            {
                //If min > ai.Minimum And max < ai.Maximum Then
                //Create a virtual channel
                ch = analogReadTask.AIChannels.CreateVoltageChannel(lines, "", config, min, max, AIVoltageUnits.Volts);

                //Verify the Task
                analogReadTask.Control(TaskAction.Verify);
                //InitializeDataTable(myTask.AIChannels, DataTable)

                AnalogMultiChannelReader reader = new AnalogMultiChannelReader(analogReadTask.Stream);

                analogReadTask.Start();
                channelData2 = reader.ReadWaveform(nsamples);
                analogReadTask.Stop();

                Debug.Print(String.Format("0x{0:X}", channelData2));
                return(0);
                //Else

                //End If

                //Update the Acquired Sample Table
                //dataToDataTable(data, DataTable)
                //acquisitionDataGrid.DataSource = DataTable
            }
            catch (DaqException ex) {
                DaqError(ex.Message);
            }
            finally {
                analogReadTask.Dispose();
                Array.Copy(channelData2, channelData, analogReadTask.AIChannels.Count);
                channelData = channelData2;
            }
            return(0);
        }
Example #6
0
        /// <summary>
        /// 配置Ao输出任务
        /// </summary>
        /// <returns></returns>
        private API_RETURN_CODE ConfigAoTask()
        {
            API_RETURN_CODE code = API_RETURN_CODE.API_SUCCESS;

            try
            {
                m_aoTask = new Task();

                m_aoTask.AOChannels.CreateVoltageChannel(GetAoPhysicalChannelName(), "", -10.0, 10.0, AOVoltageUnits.Volts);
                m_aoTask.Control(TaskAction.Verify);

                m_aoTask.Timing.SampleClockRate = m_params.AoSampleRate;
                m_aoTask.Timing.ConfigureSampleClock("",
                                                     m_aoTask.Timing.SampleClockRate,
                                                     SampleClockActiveEdge.Rising,
                                                     SampleQuantityMode.ContinuousSamples,
                                                     m_params.AoSampleCountPerFrame);

                // 路由Ao Sample Clcok到PFI0
                //if (m_config.Debugging)
                //{
                //    Logger.Info(string.Format("route ao sample clock to PFI0."));
                //    m_aoTask.ExportSignals.SampleClockOutputTerminal = string.Concat("/", NI_CARD_NAME_DEFAULT, "/", "PFI0");
                //}

                //string source = m_sysConfig.GetStartSyncSignal();
                //m_aoTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger(source, DigitalEdgeStartTriggerEdge.Rising);

                // 写入波形
                AnalogMultiChannelWriter  writer = new AnalogMultiChannelWriter(m_aoTask.Stream);
                AnalogWaveform <double>[] waves;
                if (m_config.GetScanMirrorNum() == SCAN_MIRROR_NUM.THREEE)
                {
                    waves    = new AnalogWaveform <double> [3];
                    waves[2] = AnalogWaveform <double> .FromArray1D(m_waver.Y2Wave);
                }
                else
                {
                    waves = new AnalogWaveform <double> [2];
                }
                waves[0] = AnalogWaveform <double> .FromArray1D(m_waver.XWave);

                waves[1] = AnalogWaveform <double> .FromArray1D(m_waver.Y1Wave);

                writer.WriteWaveform(false, waves);
            }
            catch (Exception e)
            {
                Logger.Error(string.Format("config ao task exception: [{0}].", e));
                code = API_RETURN_CODE.API_FAILED_NI_CONFIG_AO_TASK_EXCEPTION;
            }
            return(code);
        }
Example #7
0
        private void Start()
        {
            Cursor.Current = Cursors.WaitCursor;
            try
            {
                // 创建模拟输出任务
                galvTask = new Task();
                // 创建模拟电压输出通道
                galvTask.AOChannels.CreateVoltageChannel("Dev1/ao0:2", "", -10.0, 10.0, AOVoltageUnits.Volts);
                // 验证任务
                galvTask.Control(TaskAction.Verify);

                double        desiredFrequency = aoSampleRate / sampleCountPerAO;
                double        samplesPerBuffer = sampleCountPerAO;
                double        cyclesPerBuffer  = 1.0;
                WaveGenerator wave             = new WaveGenerator(
                    galvTask.Timing, desiredFrequency, samplesPerBuffer, cyclesPerBuffer, WaveformType.GalvWave, 2.0);

                // configure the sample clock with the calculated rate
                galvTask.Timing.ConfigureSampleClock("",
                                                     wave.ResultingSampleClockRate,
                                                     SampleClockActiveEdge.Rising,
                                                     SampleQuantityMode.ContinuousSamples, sampleCountPerAO);

                AnalogMultiChannelWriter  writer = new AnalogMultiChannelWriter(galvTask.Stream);
                AnalogWaveform <double>[] waves  = new AnalogWaveform <double> [3];
                waves[0] = AnalogWaveform <double> .FromArray1D(xWaves);

                waves[1] = AnalogWaveform <double> .FromArray1D(y1Waves);

                waves[2] = AnalogWaveform <double> .FromArray1D(y2Waves);

                //write data to buffer
                writer.WriteWaveform(false, waves);

                //start writing out data
                galvTask.Start();
            }
            catch (DaqException e)
            {
                Logger.Error(string.Format("daq exception [{0}].", e));
                MessageBox.Show(e.Message);
                galvTask.Dispose();
            }
            Cursor.Current = Cursors.Default;
        }
Example #8
0
 public MainWindow()
 {
     sim          = new AirHeaterSimulation(21.5, 0);
     airHeaterCom = new SimulatedHeaterReader(new LowPassFilter(21.5), sim);
     //airHeaterCom = new AirHeaterReader(new LowPassFilter(21.5));
     //airHeater = new DaqReader(new LowPassFilter(21.5));
     analogWaveform = new AnalogWaveform <double>(0);
     //unfilteredAnalogWaveform = new AnalogWaveform<double>(0);
     InitializeComponent();
     TemperatureGraph.DataSource = analogWaveform;
     //TemperatureGraphUnfiltered.DataSource = unfilteredAnalogWaveform;
     DataContext = this;
     RunViewUpdater();
     pidControl = new PidController(airHeaterCom);
     //realPid = new PidReader();
     opcClient = new OpcClient(airHeaterCom, pidControl);
     SetPoint  = 25;
 }
Example #9
0
        private void AnalogInCallback(IAsyncResult ar)
        {
            try
            {
                if (runningTask != null && runningTask == ar.AsyncState)
                {
                    data = reader.EndReadWaveform(ar);
                    //data.Samples
                    BufReadDAQReceived(data.GetRawData());

                    reader.BeginMemoryOptimizedReadWaveform(iInputOutputSamples, inputCallback, inputTask, data);
                }
            }
            catch (DaqException ex)
            {
                WarningDAQUpdate?.Invoke(ex.Message);
                StopTask();
            }
        }
Example #10
0
        private void frmDAQmxTest_Load(object sender, EventArgs e)
        {
            cbxDevices.Items.AddRange(DaqSystem.Local.Devices);
            cbxChannels.Items.AddRange(DaqSystem.Local.GetPhysicalChannels(PhysicalChannelTypes.AI, PhysicalChannelAccess.External));

            using (var tempTask = DaqSystem.Local.LoadTask("MyTemperatureTask"))
            {
                AnalogSingleChannelReader reader = new AnalogSingleChannelReader(tempTask.Stream);
                tempTask.Start();
                IAsyncResult            async    = reader.BeginReadWaveform(-1, null, null);
                AnalogWaveform <double> waveform = reader.EndReadWaveform(async);
                waveform.Timing = WaveformTiming.CreateWithRegularInterval(TimeSpan.FromSeconds(3), DateTime.Now);
                xAxis1.MajorDivisions.LabelFormat = new FormatString(FormatStringMode.DateTime, "h:mm:ss tt");
                waveformGraphTemp.PlotWaveform(waveform,
                                               new AnalogWaveformPlotOptions(AnalogWaveformPlotDisplayMode.Time,
                                                                             AnalogWaveformPlotScaleMode.Raw));
                tempTask.Stop();
            }
        }
Example #11
0
        private void AnalogInCallback(IAsyncResult ar)
        {
            try
            {
                if (runningTask != null && runningTask == ar.AsyncState)
                {
                    // Read the available data from the channels
                    data = analogInReader.EndReadWaveform(ar);

                    //package it into a form LSL likes (samples by channel double[,])
                    var results = data.Select(analogWaveform => analogWaveform.GetRawData()).ToList();
                    var arr = new double[results[0].Length,results.Count];
                    for (int i = 0; i < results.Count; i++)
                    {
                        for (int j = 0; j < results[0].Length; j++)
                        {
                            arr[j, i] = results[i][j];
                        }
                    }
                    //stuff it out.
                    Outlet.push_chunk(arr);

                    // Plot your data here
                    dataToDataTable(data, ref dataTable);

                    analogInReader.BeginMemoryOptimizedReadWaveform(Convert.ToInt32(samplesPerChannelNumeric.Value),
                        analogCallback, myTask, data);
                }
            }
            catch (DaqException exception)
            {
                // Display Errors
                MessageBox.Show(exception.Message);
                runningTask = null;
                myTask.Dispose();
                stopButton.Enabled = false;
                startButton.Enabled = true;
            }
        }
        private void dataToDataTable(AnalogWaveform<double>[] sourceArray, ref DataTable dataTable)
        {
            // Iterate over channels
            int currentLineIndex = 0;

            foreach (AnalogWaveform<double> waveform in sourceArray)
            {

                for (int sample = 0; sample < waveform.Samples.Count; ++sample)
                {
                    if (sample == 1)
                        break;

                    målinger.Add(waveform.Samples[sample].Value);

                }
                currentLineIndex++;
                antalmålinger++;
            }
        }
Example #13
0
        private void DaqInit()
        {
            try
            {
                daqTask  = new NationalInstruments.DAQmx.Task();
                daqTask2 = new NationalInstruments.DAQmx.Task();
                daqTask3 = new NationalInstruments.DAQmx.Task();
                daqTask.AIChannels.CreateVoltageChannel("Dev1/ai0", "", (AITerminalConfiguration)(-1), -10, 10, AIVoltageUnits.Volts);
                daqTask.AIChannels.CreateVoltageChannel("Dev1/ai1", "", (AITerminalConfiguration)(-1), -10, 10, AIVoltageUnits.Volts);
                daqTask2.AOChannels.CreateVoltageChannel("Dev1/ao0", "", -10, 10, AOVoltageUnits.Volts);
                daqTask2.AOChannels.CreateVoltageChannel("Dev1/ao1", "", -10, 10, AOVoltageUnits.Volts);
                daqTask.Timing.ConfigureSampleClock("", sampleRate, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples, sampleRate);
                daqTask.AIChannels.All.DataTransferMechanism = AIDataTransferMechanism.Dma;

                daqTask2.Timing.ConfigureSampleClock("", sampleRate, SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, sampleRate);
                daqTask2.AOChannels.All.DataTransferMechanism = AODataTransferMechanism.Dma;
                daqTask2.Stream.WriteRegenerationMode         = WriteRegenerationMode.DoNotAllowRegeneration;
                reader = new AnalogMultiChannelReader(daqTask.Stream);
                int inBufSize1 = sampleRate, inBufSize2 = 2 * sampleRate;

                inDriveSignal = reader.ReadWaveform(inBufSize1);

                /*fftw_plan mplan;
                 * double[] din = new double[inBufSize1];
                 * double[] freq = new double[inBufSize1*2];
                 * GCHandle hdin = GCHandle.Alloc(din, GCHandleType.Pinned);
                 * GCHandle hdout = GCHandle.Alloc(freq, GCHandleType.Pinned);
                 * fftw_complexarray min = new fftw_complexarray(din);
                 * fftw_complexarray mout = new fftw_complexarray(freq);
                 * IntPtr fplan5 = fftw.dft_r2c_1d(sampleRate, hdin.AddrOfPinnedObject(), hdout.AddrOfPinnedObject(), fftw_flags.Estimate);
                 * Array.Copy(inDriveSignal[0].GetRawData(), din, inBufSize1);
                 * fftw.execute(fplan5);
                 * measuredFreq1 = (double)Util.AbsMaxIndex(freq) / 2;*/

                /*int rem = (int)((double)(measuredFreq1 - (int)measuredFreq1) * 1000);
                 * int mul;
                 * if (rem > 0)
                 * {
                 *  mul = 1000 / (int)Integers.GCD(rem, 1000);
                 *  measuredFreq1 *= mul;
                 *
                 * }*/

                //Array.Copy(inDriveSignal[1].GetRawData(), din, inBufSize1);
                //fftw.execute(fplan5);
                //measuredFreq2 = (double)Util.AbsMaxIndex(freq) / 2;
                ZX1 = Util.GetZeroCrossings(inDriveSignal[0].GetRawData());
                ZX2 = Util.GetZeroCrossings(inDriveSignal[1].GetRawData());

                /*rem = (int)((double)(measuredFreq2 - (int)measuredFreq2) * 1000);
                 * if (rem > 0)
                 * {
                 *  mul = 1000 / (int)Integers.GCD(rem, 1000);
                 *  measuredFreq2 *= mul;
                 * }*/
                //samplePerChannel = (int)Math.Max(ch1, ch2);
                //sampleRate = 500*(int)Integers.LCM((long)measuredFreq1, (long)measuredFreq2);
                samplePerChannel = sampleRate / 25;
                daqTask2.EveryNSamplesWrittenEventInterval = samplePerChannel;
                daqTask2.EveryNSamplesWritten += daqTask2_EveryNSamplesWritten;
                writer  = new AnalogMultiChannelWriter(daqTask2.Stream);
                bufsize = sampleRate;

                waveX   = new double[180][];
                waveY   = new double[180][];
                outWave = new double[2, samplePerChannel];
                for (int i = 0; i < 180; i++)
                {
                    waveX[i] = new double[bufsize];
                    waveY[i] = new double[bufsize];
                }
                waveX[0] = inDriveSignal[0].GetRawData(0, bufsize);
                waveY[0] = inDriveSignal[1].GetRawData(0, bufsize);

                //Array.Copy(waveX[0], waveX[0].Length / 2, waveY[0], 0, waveY[0].Length / 2);
                //Array.Copy(waveX[0], 0, waveY[0], waveY[0].Length / 2, waveY[0].Length / 2);

                // initialize rotations
                for (int i = 1; i < 180; i++)
                {
                    for (int j = 0; j < bufsize; j++)
                    {
                        double theta = ((i) / 180.0) * Math.PI;
                        double x = waveX[0][j]; double y = waveY[0][j];
                        waveX[i][j] = x * Math.Cos(theta) - y * Math.Sin(theta);
                        waveY[i][j] = x * Math.Sin(theta) + y * Math.Cos(theta);
                    }
                }

                double[] X = new double[samplePerChannel];
                double[] Y = new double[samplePerChannel];

                Array.Copy(waveX[0], ZX1[1], X, 0, samplePerChannel);
                Array.Copy(waveY[0], ZX2[1], Y, 0, samplePerChannel);
                sampleIndex  = samplePerChannel;
                sampleIndex2 = samplePerChannel;
                AnalogWaveform <double>[] waves = { AnalogWaveform <double> .FromArray1D(X), AnalogWaveform <double> .FromArray1D(Y) };
                writer.WriteWaveform <double>(false, waves);
                daqTask.Timing.ConfigureSampleClock("", sampleRate, SampleClockActiveEdge.Rising, SampleQuantityMode.HardwareTimedSinglePoint, 0);
                double[] sample;
                bool     negative = false;

                daqTask2.Start();
                //daqTask2.AOChannels.All.DataTransferMechanism = AODataTransferMechanism.Dma;
                dcOffsetX = dcOffsetY = 0;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void AnalogInCallback(IAsyncResult ar)
        {
            try
            {
                if (runningTask != null && runningTask == ar.AsyncState)
                {
                    // Read the available data from the channels
                    data = analogInReader.EndReadWaveform(ar);

                    double[] values = data[0].GetRawData(0, data[0].SampleCount);
                    float[] dataFloat = new float[data[0].SampleCount];
                    SignalData = values;
                    byte[] arrayByte = new byte[SignalData.Count() * 4];

                    for (int i = 0; i < SignalData.Length; i++)
                    {
                        dataFloat[i] = Convert.ToSingle(SignalData[i]);
                    }
                    byte[] dataByte = myTask.Stream.ReadRaw(data[0].SampleCount);

                    float[] dataFloat2 = new float[data[0].SampleCount];

                    for (int i = 0; i < SignalData.Length; i++)
                    {
                        dataFloat2[i] = BitConverter.ToSingle(dataByte, i * 4);
                    }
                    //Record Data
                    if (isRecording)
                    {
                        int iter = 0;
                        for (int i = 0; i < SignalData.Count(); i++)
                        {
                            byte[] temp = BitConverter.GetBytes(dataFloat[i]);
                            for (int j = 0; j < 4; j++)
                            {
                                arrayByte[iter] = temp[j];
                                iter++;
                            }
                        }

                        //byte[] arrayByte = EnvironmentFunction.ConvertDoubleToByteArray(signalData, Convert.ToInt16(bitsPerSample));
                        ((ObjectRecordWAV)obRecord).WAVWriter.Write(arrayByte, 0, arrayByte.Length);
                        //((ObjectRecordWAV)obRecord).WAVWriter.WriteSamples(dataFloat, 0, dataFloat.Length);
                        //for (int i = 0; i < signalData.Length; i++)
                        //{
                        //    ((ObjectRecordWAV)obRecord).WAVWriter.WriteSample((float)signalData[i]);
                        //}
                    }

                    //OnDataChange(this, new OSequenceDataUpdateEventArgs(values));

                    analogInReader.BeginMemoryOptimizedReadWaveform(Convert.ToInt32(sampleRead),
                        analogCallback, myTask, data);

                }
            }
            catch (DaqException exception)
            {
                // Display Errors
                MessageBox.Show(exception.Message);
                runningTask = null;
                myTask.Dispose();
            }
        }
        // Method to set up the recording side of neurorighter
        private bool NRAcquisitionSetup()
        {
            lock (this)
            {
                if (!taskRunning)
                {
                    try
                    {

                        this.Cursor = Cursors.WaitCursor;
                       if (switch_record.Value)
                        {
                            // Create file name
                            if (filenameBase == null) //user hasn't specified a file
                                button_BrowseOutputFile_Click(null, null); //call file selection routine
                            if (filenameBase == null) //this happens if the user pressed cancel for the dialog
                            {
                                MessageBox.Show("An output file must be selected before recording."); //display an error message
                                this.Cursor = Cursors.Default;
                                return true;
                            }

                            // If the user is just doing repeated recordings
                            if (checkbox_repeatRecord.Checked || Properties.Settings.Default.useFidTimeStamp)
                            {
                                DateTime nowDate = DateTime.Now;//Get current time (local to computer);
                                string datePrefix = nowDate.ToString("'-'yyyy'-'MM'-'dd'-'HH'-'mm'-'ss");
                                filenameBase = originalNameBase + datePrefix;
                            }

                            // Look for old files with same name
                            string[] matchFiles;
                            try
                            {
                                matchFiles = Directory.GetFiles(currentSaveDir, currentSaveFile + "*");
                            }
                            catch
                            {
                                matchFiles = new string[0];
                            }

                            if (matchFiles.Length > 0)
                            {
                                DialogResult dr = MessageBox.Show("File " + filenameBase + " exists. Overwrite?",
                                    "NeuroRighter Warning", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);

                                if (dr == DialogResult.No)
                                    button_BrowseOutputFile_Click(null, null); //call file selection routine
                                else if (dr == DialogResult.Cancel)
                                {
                                    this.Cursor = Cursors.Default;
                                    return true;
                                }
                            }

                            // Set file base name + number of channels
                            recordingSettings.SetFID(filenameBase);
                            recordingSettings.SetNumElectrodes(numChannels);
                        }

                        // Find out how many devs and channels/dev we are going to need
                        int numDevices = (numChannels > 32 ? Properties.Settings.Default.AnalogInDevice.Count : 1);
                        numChannelsPerDev = (numChannels < 32 ? numChannels : 32);

                        // Set spike buffer lengths
                        spikeBufferLength = Convert.ToInt32(Properties.Settings.Default.ADCPollingPeriodSec * Properties.Settings.Default.RawSampleFrequency);
                        lfpBufferLength = Convert.ToInt32(Properties.Settings.Default.ADCPollingPeriodSec * Properties.Settings.Default.LFPSampleFrequency);

                        // Create spike aquisition task list
                        spikeTask = new List<Task>(numDevices);
                        Properties.Settings.Default.numSpikeTasks = numDevices;
                        NRAIChannelCollection spikeAqSet = new NRAIChannelCollection(numDevices, numChannelsPerDev);
                        spikeAqSet.SetupSpikeCollection(ref spikeTask);

                        // Check audio and video properties
                        if (Properties.Settings.Default.UseSingleChannelPlayback)
                            spikeOutTask = new Task("spikeOutTask"); //For audio output
                        if (checkBox_video.Checked) //NB: This can't be checked unless video is enabled (no need to check properties)
                            triggerTask = new Task("triggerTask");

                        // Set MUA sample rate
                        double muaSamplingRate = spikeSamplingRate / MUA_DOWNSAMPLE_FACTOR;

                        //Add LFP channels, if configured
                        if (Properties.Settings.Default.SeparateLFPBoard && Properties.Settings.Default.UseLFPs)
                        {
                            lfpTask = new Task("lfpTask");
                            for (int i = 0; i < Properties.Settings.Default.NumChannels; ++i)
                                lfpTask.AIChannels.CreateVoltageChannel(Properties.Settings.Default.LFPDevice + "/ai" + i.ToString(), "",
                                    AITerminalConfiguration.Nrse, -10.0, 10.0, AIVoltageUnits.Volts);
                            setGain(lfpTask, Properties.Settings.Default.LFPgain);
                            lfpTask.Control(TaskAction.Verify);
                        }

                        //Add EEG channels, if configured
                        if (Properties.Settings.Default.UseEEG)
                        {

                            eegTask = new Task("eegTask");
                            for (int i = 0; i < Properties.Settings.Default.EEGNumChannels; ++i)
                                eegTask.AIChannels.CreateVoltageChannel(Properties.Settings.Default.EEGDevice + "/ai" +
                                    (i).ToString(), "", AITerminalConfiguration.Nrse, -10.0, 10.0, AIVoltageUnits.Volts);
                            setGain(eegTask, (double)Properties.Settings.Default.EEGGain);
                            eegTask.Control(TaskAction.Verify);
                            eegSamplingRate = Properties.Settings.Default.EEGSamplingRate;
                        }

                        //Add channel to control Cineplex, if configured
                        if (checkBox_video.Checked)
                            triggerTask.DOChannels.CreateChannel(Properties.Settings.Default.CineplexDevice + "/Port0/line0:7", "",
                                ChannelLineGrouping.OneChannelForAllLines);

                        //Change gain based on comboBox values (1-100)
                        for (int i = 0; i < spikeTask.Count; ++i)
                            setGain(spikeTask[i], Properties.Settings.Default.A2Dgain);

                        //Verify the Tasks
                        for (int i = 0; i < spikeTask.Count; ++i)
                            spikeTask[i].Control(TaskAction.Verify);
                        //if (Properties.Settings.Default.UseSingleChannelPlayback)
                        //    spikeOutTask.Control(TaskAction.Verify);

                        //Get sampling rates, set to private variables
                        spikeSamplingRate = Properties.Settings.Default.RawSampleFrequency;
                        lfpSamplingRate = Properties.Settings.Default.LFPSampleFrequency;

                        //Version with videoTask as master clock
                        if (Properties.Settings.Default.UseCineplex)
                        {
                            for (int i = 0; i < spikeTask.Count; ++i)
                            {
                                spikeTask[i].Timing.ReferenceClockSource = videoTask.Timing.ReferenceClockSource;
                                spikeTask[i].Timing.ReferenceClockRate = videoTask.Timing.ReferenceClockRate;
                            }
                        }
                        else
                        {
                            string masterclock = "/" + Properties.Settings.Default.AnalogInDevice[0].ToString() + "/10MhzRefClock";//"OnboardClock";//
                            if (!Properties.Settings.Default.UseStimulator)
                            {
                                //Deal with non M-series devices (these can't use "ReferenceClockSource"
                                Device analogInDevice = DaqSystem.Local.LoadDevice(Properties.Settings.Default.AnalogInDevice[0]);

                                if (analogInDevice.ProductCategory == ProductCategory.MSeriesDaq || analogInDevice.ProductCategory == ProductCategory.XSeriesDaq)
                                    spikeTask[0].Timing.ReferenceClockSource = masterclock; //This will be the master clock
                            }
                            else
                            {

                                spikeTask[0].Timing.ReferenceClockSource = masterclock;//stimPulseTask.Timing.ReferenceClockSource;
                                spikeTask[0].Timing.ReferenceClockRate = 10000000.0; //stimPulseTask.Timing.ReferenceClockRate;
                            }
                            for (int i = 1; i < spikeTask.Count; ++i) //Set other analog in tasks to master clock
                            {
                                spikeTask[i].Timing.ReferenceClockSource = spikeTask[0].Timing.ReferenceClockSource;
                                spikeTask[i].Timing.ReferenceClockRate = spikeTask[0].Timing.ReferenceClockRate;
                            }
                        }
                        spikeTask[0].Timing.ConfigureSampleClock("", spikeSamplingRate,
                                SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, Convert.ToInt32(Properties.Settings.Default.RawSampleFrequency / 2));
                        for (int i = 1; i < spikeTask.Count; ++i)
                        {
                            //Pipe ai dev0's sample clock to slave devices
                            spikeTask[i].Timing.ConfigureSampleClock("/" + Properties.Settings.Default.AnalogInDevice[0] + "/ai/SampleClock", spikeSamplingRate,
                                SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, Convert.ToInt32(Properties.Settings.Default.RawSampleFrequency / 2));

                            //Trigger off of ai dev0's trigger
                            spikeTask[i].Triggers.StartTrigger.ConfigureDigitalEdgeTrigger("/" + Properties.Settings.Default.AnalogInDevice[0] +
                                "/ai/StartTrigger", DigitalEdgeStartTriggerEdge.Rising);

                            // Manually allocate buffer memory
                            //spikeTask[i].Stream.Buffer.InputBufferSize = DAQ_BUFFER_SIZE_SAMPLES;
                        }

                        if (Properties.Settings.Default.SeparateLFPBoard && Properties.Settings.Default.UseLFPs)
                        {
                            lfpTask.Timing.ReferenceClockSource = spikeTask[0].Timing.ReferenceClockSource;
                            lfpTask.Timing.ReferenceClockRate = spikeTask[0].Timing.ReferenceClockRate;
                            lfpTask.Timing.ConfigureSampleClock("", lfpSamplingRate,
                                SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, Convert.ToInt32(Properties.Settings.Default.LFPSampleFrequency / 2));

                            // Manually allocate buffer memory
                            //lfpTask.Stream.Buffer.InputBufferSize = DAQ_BUFFER_SIZE_SAMPLES;
                        }
                        else
                        {
                            Properties.Settings.Default.numLFPTasks = Properties.Settings.Default.numSpikeTasks;
                        }

                        if (Properties.Settings.Default.UseEEG)
                        {
                            eegTask.Timing.ReferenceClockSource = spikeTask[0].Timing.ReferenceClockSource;
                            eegTask.Timing.ReferenceClockRate = spikeTask[0].Timing.ReferenceClockRate;
                            eegTask.Timing.ConfigureSampleClock("", eegSamplingRate,
                                SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, Convert.ToInt32(Convert.ToDouble(Properties.Settings.Default.EEGSamplingRate) / 2));

                            // Manually allocate buffer memory
                            //eegTask.Stream.Buffer.InputBufferSize = DAQ_BUFFER_SIZE_SAMPLES;
                        }

                        if (Properties.Settings.Default.UseCineplex)
                        {
                            if (checkBox_video.Checked)
                            {
                                triggerTask.Timing.ConfigureSampleClock("/" + Properties.Settings.Default.AnalogInDevice[0] + "/ai/SampleClock",
                                    spikeSamplingRate, SampleClockActiveEdge.Rising, SampleQuantityMode.FiniteSamples,
                                    3);
                            }
                            if (Properties.Settings.Default.SeparateLFPBoard && Properties.Settings.Default.UseLFPs)
                            {
                                lfpTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger("/" +
                                    Properties.Settings.Default.AnalogInDevice[0] + "/ai/StartTrigger",
                                    DigitalEdgeStartTriggerEdge.Rising);
                            }
                            if (Properties.Settings.Default.UseEEG)
                            {
                                eegTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger("/" +
                                    Properties.Settings.Default.AnalogInDevice[0] + "/ai/StartTrigger",
                                    DigitalEdgeStartTriggerEdge.Rising);
                            }
                        }

                        if (Properties.Settings.Default.UseStimulator && Properties.Settings.Default.RecordStimTimes)
                        {
                            try
                            {

                                numStimReads = new List<int>(numDevices);
                                for (int i = 0; i < spikeTask.Count; ++i)
                                    numStimReads.Add(0);
                                stimTimeTask = new Task("stimTimeTask");
                                stimTimeTask.AIChannels.CreateVoltageChannel(Properties.Settings.Default.StimInfoDevice + "/ai16", "",
                                    AITerminalConfiguration.Nrse, -10.0, 10.0, AIVoltageUnits.Volts);
                                stimTimeTask.AIChannels.CreateVoltageChannel(Properties.Settings.Default.StimInfoDevice + "/ai0", "", AITerminalConfiguration.Nrse,
                                    -10.0, 10.0, AIVoltageUnits.Volts); //For triggers

                                // Pipe the spikeTasks sample clock to PFI14 on the stim board
                                DaqSystem.Local.ConnectTerminals(spikeTask[0].Timing.ReferenceClockSource,
                                    "/" + Properties.Settings.Default.StimulatorDevice.ToString() + "/PFI0");

                                if (isNormalRecording)
                                    stimTimeTask.Timing.ReferenceClockSource = "/" + Properties.Settings.Default.StimulatorDevice.ToString() + "/PFI0";
                                else
                                    stimTimeTask.Timing.ReferenceClockSource = spikeTask[0].Timing.ReferenceClockSource;
                                stimTimeTask.Timing.ReferenceClockRate = spikeTask[0].Timing.ReferenceClockRate;
                                stimTimeTask.Timing.ConfigureSampleClock("", spikeSamplingRate,
                                    SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, Convert.ToInt32(Properties.Settings.Default.RawSampleFrequency / 2));
                                stimTimeTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger(
                                    "/" + Properties.Settings.Default.AnalogInDevice[0] + "/ai/StartTrigger", DigitalEdgeStartTriggerEdge.Rising);
                                stimTimeTask.Control(TaskAction.Verify);

                                // stim Timing Channel settings object
                                StringCollection stimTimePhysChan = new StringCollection();
                                for (int i = 0; i < stimTimeTask.AIChannels.Count; ++i)
                                {
                                    stimTimePhysChan.Add(stimTimeTask.AIChannels[i].PhysicalName);
                                }

                                // Write down the indicies corresponding to the portion of this task that will
                                // actually record stimulus infromation instead of aux analog input
                                stimTimeChanSet = new NRAIChannelCollection(stimTimePhysChan);
                                int[] stimTimeChannels = new int[] { 0, 1 };
                                stimTimeChanSet.SetupNumericalChannelOnly(stimTimeChannels);

                                // Manually allocate buffer memory
                                //stimTimeTask.Stream.Buffer.InputBufferSize = DAQ_BUFFER_SIZE_SAMPLES;

                                Console.WriteLine("NRAcquisitionSetup complete");
                            }
                            catch (Exception e)
                            {
                                MessageBox.Show(e.Message);
                            }
                        }

                        //Setup scaling coefficients (to convert digital values to voltages)
                        scalingCoeffsSpikes = new List<double[]>(spikeTask.Count);
                        for (int i = 0; i < spikeTask.Count; ++i)
                            scalingCoeffsSpikes.Add(spikeTask[0].AIChannels[0].DeviceScalingCoefficients);
                        if (Properties.Settings.Default.SeparateLFPBoard)
                            scalingCoeffsLFPs = lfpTask.AIChannels[0].DeviceScalingCoefficients;
                        if (Properties.Settings.Default.UseEEG)
                            scalingCoeffsEEG = eegTask.AIChannels[0].DeviceScalingCoefficients;

                        // Setup auxiliary recording tasks
                        if (Properties.Settings.Default.useAuxAnalogInput)
                        {
                            // Set up the aux channel set
                            auxChanSet = new NRAIChannelCollection(Properties.Settings.Default.auxAnalogInChan);

                            if (Properties.Settings.Default.auxAnalogInDev == Properties.Settings.Default.StimInfoDevice
                                && Properties.Settings.Default.RecordStimTimes)
                            {
                                // In this case we are recording both stimulus times and aux analog input times on the same
                                // DAQ, so we need to just make the auxAnInTask reference the stimulus timing task
                                twoAITasksOnSingleBoard = true;
                                auxAnInTask = stimTimeTask;
                                auxChanSet.SetupAuxCollection(ref auxAnInTask);
                            }
                            else
                            {
                                // In this case there is no conflict for AI, so we can create a dedicated task for aux analog input
                                twoAITasksOnSingleBoard = false;
                                auxAnInTask = new Task("AuxiliaryAnalogInput");
                                auxChanSet.SetupAuxCollection(ref auxAnInTask);

                                auxAnInTask.Timing.ReferenceClockSource = spikeTask[0].Timing.ReferenceClockSource;
                                auxAnInTask.Timing.ReferenceClockRate = spikeTask[0].Timing.ReferenceClockRate;

                                //Pipe ai dev0's sample clock to slave devices
                                auxAnInTask.Timing.ConfigureSampleClock("", spikeSamplingRate,
                                    SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, Convert.ToInt32(Properties.Settings.Default.RawSampleFrequency / 2));
                                auxAnInTask.Triggers.StartTrigger.ConfigureDigitalEdgeTrigger("/Dev1/ai/StartTrigger", DigitalEdgeStartTriggerEdge.Rising);

                                // Manually allocate buffer memory
                                // auxAnInTask.Stream.Buffer.InputBufferSize = DAQ_BUFFER_SIZE_SAMPLES;

                                // Create space for the buffer
                                auxAnData = new double[auxChanSet.numericalChannels.Length, spikeBufferLength];

                            }

                        }

                        if (Properties.Settings.Default.useAuxDigitalInput)
                        {
                            auxDigInTask = new Task("AuxiliaryDigitalInput");
                            auxDigInTask.DIChannels.CreateChannel(Properties.Settings.Default.auxDigitalInPort,
                                "Auxiliary Digitial In", ChannelLineGrouping.OneChannelForAllLines);

                            auxDigInTask.Timing.ConfigureSampleClock("", spikeSamplingRate,
                                SampleClockActiveEdge.Rising, SampleQuantityMode.ContinuousSamples, Convert.ToInt32(Properties.Settings.Default.RawSampleFrequency / 2));
                            auxDigInTask.Timing.SampleClockSource = spikeTask[0].Timing.SampleClockTerminal;

                            // Manually allocate buffer memory
                            // auxDigInTask.Stream.Buffer.InputBufferSize = DAQ_BUFFER_SIZE_SAMPLES;
                        }

                        #region Setup_Plotting

                        numSnipsDisplayed = (int)numericUpDown_NumSnipsDisplayed.Value;

                        #region PlotData_Buffers
                        //***********************
                        //Make PlotData buffers
                        //***********************
                        int downsample, numRows, numCols;
                        const double spikeplotlength = 0.25; //in seconds
                        switch (Properties.Settings.Default.NumChannels)
                        {
                            case 16:
                                numRows = numCols = 4;
                                downsample = 10;
                                break;
                            case 32:
                                numRows = numCols = 6;
                                downsample = 15;
                                break;
                            case 64:
                                numRows = numCols = 8;
                                downsample = 20; //if this gets really small, LFP data won't plot
                                break;
                            default:
                                numRows = numCols = 4;
                                downsample = 5;
                                break;
                        }

                        //Create plot colormap
                        NRBrainbow = (64).GenerateBrainbow();
                        NRSnipBrainbow = (64).GenerateSnipBrainbow();
                        NRUnitBrainbow = (64).GenerateUnitBrainbow();

                        //Initialize graphs
                        if (spikeGraph != null) { spikeGraph.Dispose(); spikeGraph = null; }
                        spikeGraph = new GridGraph();
                        int samplesPerPlot = (int)(Math.Ceiling(Properties.Settings.Default.ADCPollingPeriodSec * spikeSamplingRate / downsample) * (spikeplotlength / Properties.Settings.Default.ADCPollingPeriodSec));
                        spikeGraph.setup(numRows, numCols, samplesPerPlot, false, 1 / 4.0, spikeTask[0].AIChannels.All.RangeHigh * 2.0);
                        spikeGraph.setMinMax(0, (float)(samplesPerPlot * numCols) - 1,
                            (float)(spikeTask[0].AIChannels.All.RangeLow * (numRows * 2 - 1)), (float)(spikeTask[0].AIChannels.All.RangeHigh));
                        spikeGraph.Dock = DockStyle.Fill;
                        spikeGraph.Parent = tabPage_spikes;

                        if (Properties.Settings.Default.UseLFPs)
                        {
                            if (lfpGraph != null) { lfpGraph.Dispose(); lfpGraph = null; }
                            lfpGraph = new RowGraph();
                            lfpGraph.setup(numChannels, (int)((Math.Ceiling(Properties.Settings.Default.ADCPollingPeriodSec * lfpSamplingRate / downsample) * (5 / Properties.Settings.Default.ADCPollingPeriodSec))),
                                5.0, spikeTask[0].AIChannels.All.RangeHigh * 2.0);
                            if (Properties.Settings.Default.SeparateLFPBoard)
                                lfpGraph.setMinMax(0, 5 * (int)(Math.Ceiling(Properties.Settings.Default.ADCPollingPeriodSec * lfpSamplingRate / downsample) / Properties.Settings.Default.ADCPollingPeriodSec) - 1,
                                    (float)(lfpTask.AIChannels.All.RangeLow * (numChannels * 2 - 1)), (float)(lfpTask.AIChannels.All.RangeHigh));
                            else
                                lfpGraph.setMinMax(0, 5 * (int)(Math.Ceiling(Properties.Settings.Default.ADCPollingPeriodSec * lfpSamplingRate / downsample) / Properties.Settings.Default.ADCPollingPeriodSec) - 1,
                                    (float)(spikeTask[0].AIChannels.All.RangeLow * (numChannels * 2 - 1)), (float)(spikeTask[0].AIChannels.All.RangeHigh));
                            lfpGraph.Dock = DockStyle.Fill;
                            lfpGraph.Parent = tabPage_LFPs;
                        }

                        if (Properties.Settings.Default.ProcessMUA)
                        {
                            if (muaGraph != null) { muaGraph.Dispose(); muaGraph = null; }
                            muaGraph = new RowGraph();
                            muaGraph.setup(numChannels, (int)((Math.Ceiling(Properties.Settings.Default.ADCPollingPeriodSec * muaSamplingRate / downsample) * (5 / Properties.Settings.Default.ADCPollingPeriodSec))),
                                5.0, spikeTask[0].AIChannels.All.RangeHigh * 2.0);
                            muaGraph.setMinMax(0, 5 * (int)(Math.Ceiling(Properties.Settings.Default.ADCPollingPeriodSec * muaSamplingRate / downsample) / Properties.Settings.Default.ADCPollingPeriodSec) - 1,
                                    (float)(spikeTask[0].AIChannels.All.RangeLow * (numChannels * 2 - 1)), (float)(spikeTask[0].AIChannels.All.RangeHigh));
                            muaGraph.Dock = DockStyle.Fill;
                            muaGraph.Parent = tabPage_MUA;

                            muaPlotData = new PlotDataRows(numChannels, downsample, (int)(muaSamplingRate * 5), muaSamplingRate,
                                    (float)spikeTask[0].AIChannels.All.RangeHigh * 2F, 0.5, 5, Properties.Settings.Default.ADCPollingPeriodSec);
                            //muaPlotData.setGain(Properties.Settings.Default.LFPDisplayGain);

                            //muaGraph.setDisplayGain(Properties.Settings.Default.LFPDisplayGain);
                            muaPlotData.dataAcquired += new PlotData.dataAcquiredHandler(muaPlotData_dataAcquired);
                        }

                        if (Properties.Settings.Default.UseEEG)
                        {
                            if (eegGraph != null) { eegGraph.Dispose(); eegGraph = null; }
                            eegGraph = new RowGraph();
                            eegGraph.setup(Properties.Settings.Default.EEGNumChannels, (int)((Math.Ceiling(Properties.Settings.Default.ADCPollingPeriodSec * eegSamplingRate / downsample) * (5 / Properties.Settings.Default.ADCPollingPeriodSec))),
                                5.0, eegTask.AIChannels.All.RangeHigh * 2.0);
                            eegGraph.setMinMax(0, 5 * (int)(Math.Ceiling(Properties.Settings.Default.ADCPollingPeriodSec * eegSamplingRate / downsample) / Properties.Settings.Default.ADCPollingPeriodSec) - 1,
                                    (float)(eegTask.AIChannels.All.RangeLow * (Properties.Settings.Default.EEGNumChannels * 2 - 1)), (float)(eegTask.AIChannels.All.RangeHigh));
                            eegGraph.Dock = DockStyle.Fill;
                            eegGraph.Parent = tabPage_EEG;
                        }

                        resetSpkWfm(); //Take care of spike waveform graph

                        double ampdec = (1 / Properties.Settings.Default.PreAmpGain);

                        spikePlotData = new PlotDataGrid(numChannels, downsample, (int)(spikeSamplingRate), spikeSamplingRate,
                            (float)(spikeTask[0].AIChannels.All.RangeHigh * 2.0), numRows, numCols, spikeplotlength,
                            Properties.Settings.Default.ChannelMapping, Properties.Settings.Default.ADCPollingPeriodSec);
                        spikePlotData.dataAcquired += new PlotData.dataAcquiredHandler(spikePlotData_dataAcquired);
                        spikePlotData.setGain(Properties.Settings.Default.SpikeDisplayGain);
                        spikeGraph.setDisplayGain(Properties.Settings.Default.SpikeDisplayGain);

                        if (Properties.Settings.Default.UseLFPs)
                        {
                            if (Properties.Settings.Default.SeparateLFPBoard)
                                lfpPlotData = new PlotDataRows(numChannels, downsample, (int)(lfpSamplingRate * 5), lfpSamplingRate,
                                    (float)lfpTask.AIChannels.All.RangeHigh * 2F, 0.5, 5, Properties.Settings.Default.ADCPollingPeriodSec);
                            else lfpPlotData = new PlotDataRows(numChannels, downsample, (int)(lfpSamplingRate * 5), lfpSamplingRate,
                                    (float)spikeTask[0].AIChannels.All.RangeHigh * 2F, 0.5, 5, Properties.Settings.Default.ADCPollingPeriodSec);
                            lfpPlotData.setGain(Properties.Settings.Default.LFPDisplayGain);

                            lfpGraph.setDisplayGain(Properties.Settings.Default.LFPDisplayGain);
                            lfpPlotData.dataAcquired += new PlotData.dataAcquiredHandler(lfpPlotData_dataAcquired);
                        }

                        waveformPlotData = new EventPlotData(numChannels, spikeDet.NumPre + spikeDet.NumPost + 1, (float)(spikeTask[0].AIChannels.All.RangeHigh * 2F),
                            numRows, numCols, numSnipsDisplayed, Properties.Settings.Default.ChannelMapping);
                        waveformPlotData.setGain(Properties.Settings.Default.SpkWfmDisplayGain);
                        spkWfmGraph.setDisplayGain(Properties.Settings.Default.SpkWfmDisplayGain);
                        waveformPlotData.dataAcquired += new EventPlotData.dataAcquiredHandler(waveformPlotData_dataAcquired);
                        waveformPlotData.start();
                        #endregion

                        if (Properties.Settings.Default.UseEEG)
                        {
                            eegPlotData = new PlotDataRows(Properties.Settings.Default.EEGNumChannels, downsample, (int)(eegSamplingRate * 5), eegSamplingRate,
                                    (float)eegTask.AIChannels.All.RangeHigh * 2F, 0.5, 5, Properties.Settings.Default.ADCPollingPeriodSec);
                            eegPlotData.setGain(Properties.Settings.Default.EEGDisplayGain);

                            eegGraph.setDisplayGain(Properties.Settings.Default.EEGDisplayGain);
                            eegPlotData.dataAcquired += new PlotData.dataAcquiredHandler(eegPlotData_dataAcquired);
                        }

                        if (Properties.Settings.Default.useAuxAnalogInput)
                        {
                            // Remove existing plots
                            for (int i = scatterGraph_AuxAnalogData.Plots.Count-1; i > 0; --i)
                            {
                                scatterGraph_AuxAnalogData.Plots.RemoveAt(i);
                            }
                            // Initialize the aux data scatter graph with a plot for each aux Analog channel
                            for (int i = 0; i < Properties.Settings.Default.auxAnalogInChan.Count-1; ++i)
                            {
                                ScatterPlot p = new ScatterPlot();
                                scatterGraph_AuxAnalogData.Plots.Add(p);
                            }

                            // Initialize the controller
                            auxInputGraphController = new ScatterGraphController(ref scatterGraph_AuxAnalogData);

                            // Make history selector reflect current limits on input
                            //slide_AnalogDispMaxVoltage.Range = new Range(0.05, 10);
                            //slide_AnalogDispWidth.Range = new Range(2*Properties.Settings.Default.ADCPollingPeriodSec, Properties.Settings.Default.datSrvBufferSizeSec);

                        }
                        #endregion

                        #region Setup_Filters
                        //Setup filters, based on user's input
                        resetSpikeFilter();
                        if (Properties.Settings.Default.UseLFPs) resetLFPFilter();
                        resetEEGFilter();

                        muaFilter = new Filters.MUAFilter(
                            numChannels, spikeSamplingRate, spikeBufferLength,
                            Properties.Settings.Default.MUAHighCutHz,
                            Properties.Settings.Default.MUAFilterOrder,
                            MUA_DOWNSAMPLE_FACTOR,
                            Properties.Settings.Default.ADCPollingPeriodSec);

                        #endregion

                        #region Setup_DataStorage
                        //Initialize data storing matrices
                      //  numChannels = Properties.Settings.Default.NumChannels;

                        numSpikeReads = new int[spikeTask.Count];

                        filtSpikeData = new rawType[numChannels][];

                        if (Properties.Settings.Default.UseLFPs)
                        {
                            filtLFPData = new rawType[numChannels][];
                            finalLFPData = new rawType[numChannels][];
                            for (int i = 0; i < filtSpikeData.GetLength(0); ++i)
                            {
                                if (Properties.Settings.Default.SeparateLFPBoard)
                                    filtLFPData[i] = new rawType[lfpBufferLength];
                                else
                                    filtLFPData[i] = new rawType[spikeBufferLength];
                            }
                        }

                        if (Properties.Settings.Default.ProcessMUA)
                        {
                            muaData = new double[numChannels][];
                            for (int c = 0; c < numChannels; ++c)
                                muaData[c] = new double[spikeBufferLength / MUA_DOWNSAMPLE_FACTOR];
                        }

                        if (Properties.Settings.Default.UseEEG)
                        {

                            filtEEGData = new double[Properties.Settings.Default.EEGNumChannels][];
                            for (int i = 0; i < filtEEGData.GetLength(0); ++i)
                            {
                                filtEEGData[i] = new double[eegBufferLength];
                            }
                        }

                        for (int i = 0; i < filtSpikeData.GetLength(0); ++i)
                        {
                            filtSpikeData[i] = new rawType[spikeBufferLength];
                            if (Properties.Settings.Default.UseLFPs)
                                finalLFPData[i] = new rawType[lfpBufferLength];
                        }

                        if (Properties.Settings.Default.UseStimulator)
                        {
                            stimDataBuffer = new double[STIM_BUFFER_LENGTH];
                            stimJump = (double)spikeSamplingRate * 0.0001; //num. indices in 100 us of data
                        }

                        stimIndices = new List<StimTick>(5);
                        //if devices refresh rate is reset, need to reset SALPA
                        if (checkBox_SALPA.Checked)
                            resetSALPA();
                        if (spikeDet != null && isNormalRecording)
                            setSpikeDetector();
                        if (spikeDet.spikeDetector == null)
                            setSpikeDetector();

                        #endregion

                        #region Verify Tasks
                        if (Properties.Settings.Default.UseStimulator && Properties.Settings.Default.RecordStimTimes)
                            stimTimeTask.Control(TaskAction.Verify);
                        if (Properties.Settings.Default.UseEEG)
                            eegTask.Control(TaskAction.Verify);
                        if (Properties.Settings.Default.SeparateLFPBoard && Properties.Settings.Default.UseLFPs)
                            lfpTask.Control(TaskAction.Verify);
                        if (checkBox_video.Checked)
                            triggerTask.Control(TaskAction.Verify);
                        for (int i = 0; i < spikeTask.Count; ++i)
                            spikeTask[i].Control(TaskAction.Verify);
                        if (Properties.Settings.Default.useAuxAnalogInput)
                            auxAnInTask.Control(TaskAction.Verify);
                        if (Properties.Settings.Default.useAuxDigitalInput)
                            auxDigInTask.Control(TaskAction.Verify);
                        #endregion

                        SetupFileWriting();

                        //Set callbacks for data acq.
                        spikeReader = new List<AnalogMultiChannelReader>(spikeTask.Count);
                        for (int i = 0; i < spikeTask.Count; ++i)
                        {
                            spikeReader.Add(new AnalogMultiChannelReader(spikeTask[i].Stream));
                            spikeReader[i].SynchronizeCallbacks = true;
                        }
                        //if (Properties.Settings.Default.UseSingleChannelPlayback)
                        //    spikeOutWriter = new AnalogSingleChannelWriter(spikeOutTask.Stream);
                        if (checkBox_video.Checked)
                            triggerWriter = new DigitalSingleChannelWriter(triggerTask.Stream);

                        //if (Properties.Settings.Default.UseSingleChannelPlayback)
                        //    spikeOutWriter.SynchronizeCallbacks = false; //These don't use UI, so they don't need to be synched

                        spikeCallback = new AsyncCallback(AnalogInCallback_spikes);

                        if (Properties.Settings.Default.UseStimulator && Properties.Settings.Default.RecordStimTimes)
                        {
                            stimTimeReader = new AnalogMultiChannelReader(stimTimeTask.Stream);
                        }

                        if (Properties.Settings.Default.SeparateLFPBoard && Properties.Settings.Default.UseLFPs)
                        {
                            lfpReader = new AnalogUnscaledReader(lfpTask.Stream);
                            lfpReader.SynchronizeCallbacks = true;
                            lfpCallback = new AsyncCallback(AnalogInCallback_LFPs);
                        }
                        if (Properties.Settings.Default.UseEEG)
                        {
                            eegReader = new AnalogUnscaledReader(eegTask.Stream);
                            eegReader.SynchronizeCallbacks = true;
                            eegCallback = new AsyncCallback(AnalogInCallback_EEG);
                        }

                        if (Properties.Settings.Default.useAuxAnalogInput)
                        {
                            auxAnReader = new AnalogMultiChannelReader(auxAnInTask.Stream);
                            auxAnReader.SynchronizeCallbacks = true;
                            auxAnCallback = new AsyncCallback(AnalogInCallback_AuxAn);
                        }

                        if (Properties.Settings.Default.useAuxDigitalInput)
                        {
                            auxDigReader = new DigitalSingleChannelReader(auxDigInTask.Stream);
                            auxDigReader.SynchronizeCallbacks = true;
                            auxDigCallback = new AsyncCallback(AnalogInCallback_AuxDig);
                        }

                        //Setup background workers for data processing
                        bwSpikes = new List<BackgroundWorker>(spikeTask.Count);
                        bwIsRunning = new bool[spikeTask.Count];
                        for (int i = 0; i < spikeTask.Count; ++i)
                        {
                            bwSpikes.Add(new BackgroundWorker());
                            bwSpikes[i].DoWork += new DoWorkEventHandler(bwSpikes_DoWork);
                            bwSpikes[i].RunWorkerCompleted += new RunWorkerCompletedEventHandler(bwSpikes_RunWorkerCompleted);
                            bwSpikes[i].WorkerSupportsCancellation = true;
                        }

                        //Make persistent buffers for spikeData
                        spikeData = new List<AnalogWaveform<double>[]>(spikeReader.Count);
                        for (int i = 0; i < spikeReader.Count; ++i)
                        {
                            spikeData.Add(new AnalogWaveform<double>[numChannelsPerDev]);
                            for (int j = 0; j < numChannelsPerDev; ++j)
                                spikeData[i][j] = new AnalogWaveform<double>(spikeBufferLength);
                        }

                        //Make channel playback task
                        if (Properties.Settings.Default.UseSingleChannelPlayback)
                            BNCOutput = new ChannelOutput(spikeSamplingRate, 0.1, Properties.Settings.Default.ADCPollingPeriodSec, spikeTask[0],
                                Properties.Settings.Default.SingleChannelPlaybackDevice, 0);

                    }
                    catch (Exception exception)
                    {
                        //Display Errors
                        this.Cursor = Cursors.Default;
                        MessageBox.Show(exception.Message);
                        reset();
                    }

                    // Set up the DataSrv object. This is an object that publishes a nice large data history
                    // for use in closed loop control and other things
                    if (datSrv != null)
                        datSrv = null;

                    datSrv = new DataSrv(
                        Properties.Settings.Default.datSrvBufferSizeSec,
                        checkBox_SALPA.Checked,
                        SALPA_WIDTH,
                        checkBox_spikesFilter.Checked,
                        spikeDet.spikeDetectionLag
                        );

                    // Set the number of units if appropriate
                    if (spikeDet.spikeSorter != null)
                        datSrv.SetNumberOfUnits(spikeDet.spikeSorter.totalNumberOfUnits, spikeDet.spikeSorter.unit2Channel);

                    Debugger = new Logger();
                    Debugger.GrabTimer(spikeTask[0]);

                    //Send debug output to the user's application data folder
                    Debugger.SetPath(Path.Combine(Properties.Settings.Default.neurorighterAppDataPath, "neurorighter-log.txt"));

                    //Tell neuroRighter that the tasks now exist
                    taskRunning = true;
                }
                else
                {
                    Console.WriteLine("NRAcquisitionSetup was called while a task was running, and therefore setup did not execute.  Perhaps this should have thrown an error");
                }
            }

            //update gui at the end
            // Modify the UI, so user doesn't try running multiple instances of tasks

            spikeDet.numPreSamples.Enabled = false;
            spikeDet.numPostSamples.Enabled = false;
            settingsToolStripMenuItem.Enabled = false;

            button_Train.Enabled = false;
            button_SetRecordingStreams.Enabled = false;
            switch_record.Enabled = false;
            //processingSettingsToolStripMenuItem.Enabled = false;

            button_startStimFromFile.Enabled = false;
            button_startClosedLoopStim.Enabled = false;
            checkBox_SALPA.Enabled = false;

            //numericUpDown_NumSnipsDisplayed.Enabled = false;
            button_startClosedLoopStim.Enabled = false;
            button_scaleUp.Enabled = true;
            button_scaleDown.Enabled = true;
            button_scaleReset.Enabled = true;

            // Disable spike detector saving while running
            spikeDet.DisableFileMenu();
            Console.WriteLine("NRAcquisitionSetup successfully executed");
            this.Cursor = Cursors.Default;
            return false;
        }
Example #16
0
        public static void ReadCallBack(IAsyncResult ar)
        {
            try
            {
                if (runningTask != null && runningTask == ar.AsyncState)
                {
                    data = reader.EndReadWaveform(ar);
                    counter++;
                    double value = data[0].GetRawData()[0];
                    double value1 = data[1].GetRawData()[0];
                    udpClient.Connect("localhost", 60105);
                    udpClient1.Connect("localhost", 60107);
                    Byte[] sendBytes = Encoding.ASCII.GetBytes("conveyor success");

                    if (value > 4.93 && value < 5.05) {
                        System.Console.WriteLine("data length = " + value + " " + counter + " " + data[0].GetRawData().Length);
                        System.Console.WriteLine("data1 length = " + value1 + " " + counter + " " + data[1].GetRawData().Length);
                        int sentLength = udpClient.Send(sendBytes, sendBytes.Length);
                        //if (sentLength > 0) udpClient.Close();
                    }
                    if (value1 > 5.5) {
                        Byte[] sendBytes1 = Encoding.ASCII.GetBytes("contrast sensor value = " + value1);
                        int sentLength = udpClient1.Send(sendBytes1, sendBytes1.Length);
                    }

                    reader.BeginMemoryOptimizedReadWaveform(Convert.ToInt32(continuousTask.Timing.SamplesPerChannel), callBack, continuousTask, data);
                }
            }
            catch (DaqException ex)
            {

                continuousTask.Dispose();

                runningTask = null;

            }
        }
        private void AnalogInCallback(IAsyncResult ar)
        {
            try
            {
                if (runningTask != null && runningTask == ar.AsyncState)
                {
                    // Read the available data from the channels
                    data = analogInReader.EndReadWaveform(ar);

                    // Plot your data here
                    dataToDataTable(data, ref dataTable);

                    analogInReader.BeginMemoryOptimizedReadWaveform(SamplesPerChannel,
                        analogCallback, myTask, data);
                }
            }
            catch (Exception e)
            {
                // Display Errors
                runningTask = null;
                myTask.Dispose();

            }
        }
Example #18
0
        private void dataToDataTable2(AnalogWaveform<double>[] sourceArray, ref DataTable dataTable)
        {
            // Iterate over channels
            int currentLineIndex = 0;
            int i = 0;
            DataRow tmprow = dataTable.NewRow();
            int lengthOfSourceArray = sourceArray.GetLength(0);

            foreach (AnalogWaveform<double> waveform in sourceArray)
            {
                for (int sample = 0; sample < waveform.Samples.Count; sample++)
                {
                    if (waveform.Samples[i].Value > triggerSensitivity && countRows <= numOfdata)
                    {
                        if (holding == false)
                        {
                            chart1.Series[0].Points.Clear();
                            chart2.Series[0].Points.Clear();
                            holding = true;
                        }
                        startTrigger = true;
                        endTrigger = true;
                    }
                    else if (countRows >= numOfdata)
                        startTrigger = false;

                    if (sample == lengthOfSourceArray)
                        break;

                    tmprow[i] = waveform.Samples[i].Value;

                }
                i++;
                currentLineIndex++;
            }
            if (lengthOfSourceArray == 1 && startTrigger == true && endTrigger == true)
            {
                countRows++;
                if (countRows % samplingVariable == 0)
                {
                    chart1.Series[0].Points.AddXY(countRows, tmprow[0]);
                }
            }
            else if (lengthOfSourceArray == 2 && startTrigger == true && endTrigger == true)
            {
                countRows++;
                if (countRows % samplingVariable == 0)
                {
                    chart1.Series[0].Points.AddXY(countRows, tmprow[0]);
                    chart2.Series[0].Points.AddXY(countRows, tmprow[1]);
                }
            }
            if (startTrigger == true)
            {
                dataTable.Rows.Add(tmprow);
            }
            else if (startTrigger == false && countRows >= numOfdata && endTrigger == true)
            {
                if (runningTask != null)
                {
                    runningTask = null;
                    dataTableToFile(ref dataTable);

                    if (fault_stitch.Length > 0)
                    {
                        uploadToDB_faultResult();
                    }

                    // Dispose of the task
                    myTask.Dispose();
                    countRows = 0;
                    endTrigger = false;
                    holding = false;
                    measure_index++;
                    runMainPerformance2();
                    Properties.Settings.Default.jobNum++;
                    this.label3.Content = Convert.ToString(Properties.Settings.Default.jobNum);
                }
            }
        }
Example #19
0
        private void AnalogInCallback2(IAsyncResult ar)
        {
            try
            {
                if (runningTask != null && runningTask == ar.AsyncState)
                {
                    // Read the available data from the channels
                    data = analogInReader.EndReadWaveform(ar);

                    analogInReader.BeginMemoryOptimizedReadWaveform(Convert.ToInt32(Properties.Settings.Default.samplesPerChannelNumeric),
                        analogCallback, myTask, data);

                    // Plot your data here
                    dataToDataTable2(data, ref dataTable);

                }
            }
            catch (DaqException exception)
            {
                // Display Errors
                MessageBox.Show(exception.Message);
                runningTask = null;
                myTask.Dispose();
            }
        }
Example #20
0
        //double[,] data = new double[2,80000];
        private void AnalogInCallback(IAsyncResult ar)
        {
            try
            {
                if (_myTask == ar.AsyncState)
                {
                    // Read the available data from the channels
                    data = _analogInReader.EndReadWaveform(ar);

                    var samples = data[0].Samples.Select(sample => new Sample(sample.PrecisionTimeStamp, sample.Value));

                    OnCompletedSamples(new CompletedSamplesEventArgs(samples));
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
        //Asynkron callback
        // Denne metode kalder dataToDataTable og sender data og en reference med som parameter.
        // Samt sker der asynkron callback, hvis DAQ'en kører.
        private void AnalogInCallback(IAsyncResult ar)
        {
            try
            {
                if (runningTask != null && runningTask == ar.AsyncState)
                {
                    // Read the available data from the channels
                    data = analogInReader.EndReadWaveform(ar);

                    // Plot your data here
                    dataToDataTable(data, ref dataTable);

                    analogInReader.BeginMemoryOptimizedReadWaveform(Convert.ToInt32(10),
                        analogCallback, myTask, data);
                }
            }
            catch (DaqException exception)
            {
                runningTask = null;
                myTask.Dispose();
                //throw exception;
            }
        }
        // Denne metode tilføjer alle samples i sourceArray over i råData og kalder Notify der "skubber" sampleværdierne op til Logik laget.
        private void dataToDataTable(AnalogWaveform<double>[] sourceArray, ref DataTable dataTable)
        {
            // Iterate over channels
            int currentLineIndex = 0;
            List<double> råData = new List<double>();

            foreach (AnalogWaveform<double> waveform in sourceArray)
            {
                for (int sample = 0; sample < waveform.Samples.Count; ++sample)
                {
                    råData.Add(waveform.Samples[sample].Value);
                }

                Notify(råData);

                currentLineIndex++;
            }
        }
        private void dataToDataTable(AnalogWaveform<double>[] sourceArray, ref DataTable dataTable)
        {
            // Iterate over channels
            int currentLineIndex = 0;
            foreach (AnalogWaveform<double> waveform in sourceArray)
            {
                for (int sample = 0; sample < waveform.Samples.Count; ++sample)
                {
                    if (sample == 10)
                        break;

                    //dataTable.Rows[sample][currentLineIndex] = waveform.Samples[sample].Value;
                    //Flytter data fra Waveform-array til dataList:
                    dataList.Add(waveform.Samples[sample].Value);
                }
                currentLineIndex++;
            }
        }