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(); } }
/// <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)); } }
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(); } }
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); }
/// <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); }
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; }
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; }
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(); } }
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(); } }
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++; } }
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; }
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(); } }
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); } } }
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(); } }
//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++; } }