/// <summary> /// NeuroRighter's Persistant Data Server /// </summary> /// <param name="bufferSizeSeconds"> History that is stored in the Server (seconds)</param> /// <param name="salpaAccess"> Using SALPA? </param> /// <param name="salpaWidth">half width of the salpa filter</param> /// <param name="spikeFiltAccess"> Using spike filters? </param> /// <param name="spikeDetlag">lag from the spike detection settings</param> internal DataSrv(double bufferSizeSeconds, bool salpaAccess, int salpaWidth, bool spikeFiltAccess, int spikeDetlag) { // Set the polling periods aDCPollingPeriodSec = Properties.Settings.Default.ADCPollingPeriodSec; aDCPollingPeriodSamples = Convert.ToInt32(Properties.Settings.Default.ADCPollingPeriodSec * Properties.Settings.Default.RawSampleFrequency); // Set the spike server lag int spikeLag = spikeDetlag; // Figure out what servers we need to start up and start them with the correct parameters // 1. The raw server is always running rawElectrodeSrv = new RawDataSrv( Properties.Settings.Default.RawSampleFrequency, Convert.ToInt32(Properties.Settings.Default.NumChannels), bufferSizeSeconds, ADCPollingPeriodSamples, Properties.Settings.Default.numSpikeTasks); //2. SALPA data if (salpaAccess) { salpaElectrodeSrv = new RawDataSrv( Properties.Settings.Default.RawSampleFrequency, Convert.ToInt32(Properties.Settings.Default.NumChannels), bufferSizeSeconds, ADCPollingPeriodSamples, Properties.Settings.Default.numSpikeTasks); spikeLag += 2*salpaWidth; } //3. Spike Filter data if (true) { spikeBandSrv = new RawDataSrv( Properties.Settings.Default.RawSampleFrequency, Convert.ToInt32(Properties.Settings.Default.NumChannels), bufferSizeSeconds, ADCPollingPeriodSamples, Properties.Settings.Default.numSpikeTasks); } //4. LFP data if (Properties.Settings.Default.UseLFPs) { lfpSrv = new RawDataSrv( Properties.Settings.Default.LFPSampleFrequency, Convert.ToInt32(Properties.Settings.Default.NumChannels), bufferSizeSeconds, Convert.ToInt32(Properties.Settings.Default.LFPSampleFrequency * (ADCPollingPeriodSamples / Properties.Settings.Default.RawSampleFrequency)), Properties.Settings.Default.numLFPTasks); } //5. EEG data if (Properties.Settings.Default.UseEEG) { eegSrv = new RawDataSrv( Properties.Settings.Default.EEGSamplingRate, Properties.Settings.Default.EEGNumChannels, bufferSizeSeconds, Convert.ToInt32(Properties.Settings.Default.EEGSamplingRate * (ADCPollingPeriodSamples / Properties.Settings.Default.RawSampleFrequency)), 1); } //6. Auxiliary analog data if (Properties.Settings.Default.useAuxAnalogInput) { auxAnalogSrv = new RawDataSrv( Properties.Settings.Default.RawSampleFrequency, Properties.Settings.Default.auxAnalogInChan.Count, bufferSizeSeconds, ADCPollingPeriodSamples, 1); } //7. Spike data, always available spikeSrv = new EventDataSrv<SpikeEvent>( Properties.Settings.Default.RawSampleFrequency, bufferSizeSeconds, ADCPollingPeriodSamples, Properties.Settings.Default.numSpikeTasks, spikeLag, Convert.ToInt32(Properties.Settings.Default.NumChannels)); //8. Auxiliary Digital data if (Properties.Settings.Default.useAuxDigitalInput) { auxDigitalSrv = new EventDataSrv<DigitalPortEvent>( Properties.Settings.Default.RawSampleFrequency, bufferSizeSeconds, ADCPollingPeriodSamples, 1, 0, 32); } //9. Stimulus data if (Properties.Settings.Default.RecordStimTimes) { stimSrv = new EventDataSrv<ElectricalStimEvent>( Properties.Settings.Default.RawSampleFrequency, bufferSizeSeconds, ADCPollingPeriodSamples, 1, 0, 0); } }
/// <summary> /// NeuroRighter's Persistant Data Server /// </summary> /// <param name="bufferSizeSeconds"> History that is stored in the Server (seconds)</param> /// <param name="salpaAccess"> Using SALPA? </param> /// <param name="salpaWidth">half width of the salpa filter</param> /// <param name="spikeFiltAccess"> Using spike filters? </param> /// <param name="spikeDetlag">lag from the spike detection settings</param> internal DataSrv(double bufferSizeSeconds, bool salpaAccess, int salpaWidth, bool spikeFiltAccess, int spikeDetlag) { // Set the polling periods aDCPollingPeriodSec = Properties.Settings.Default.ADCPollingPeriodSec; aDCPollingPeriodSamples = Convert.ToInt32(Properties.Settings.Default.ADCPollingPeriodSec * Properties.Settings.Default.RawSampleFrequency); // Set the spike server lag int spikeLag = spikeDetlag; // Figure out what servers we need to start up and start them with the correct parameters // 1. The raw server is always running rawElectrodeSrv = new RawDataSrv( Properties.Settings.Default.RawSampleFrequency, Convert.ToInt32(Properties.Settings.Default.NumChannels), bufferSizeSeconds, ADCPollingPeriodSamples, Properties.Settings.Default.numSpikeTasks); //2. SALPA data if (salpaAccess) { salpaElectrodeSrv = new RawDataSrv( Properties.Settings.Default.RawSampleFrequency, Convert.ToInt32(Properties.Settings.Default.NumChannels), bufferSizeSeconds, ADCPollingPeriodSamples, Properties.Settings.Default.numSpikeTasks); spikeLag += 2 * salpaWidth; } //3. Spike Filter data if (true) { spikeBandSrv = new RawDataSrv( Properties.Settings.Default.RawSampleFrequency, Convert.ToInt32(Properties.Settings.Default.NumChannels), bufferSizeSeconds, ADCPollingPeriodSamples, Properties.Settings.Default.numSpikeTasks); } //4. LFP data if (Properties.Settings.Default.UseLFPs) { lfpSrv = new RawDataSrv( Properties.Settings.Default.LFPSampleFrequency, Convert.ToInt32(Properties.Settings.Default.NumChannels), bufferSizeSeconds, Convert.ToInt32(Properties.Settings.Default.LFPSampleFrequency * (ADCPollingPeriodSamples / Properties.Settings.Default.RawSampleFrequency)), Properties.Settings.Default.numLFPTasks); } //5. EEG data if (Properties.Settings.Default.UseEEG) { eegSrv = new RawDataSrv( Properties.Settings.Default.EEGSamplingRate, Properties.Settings.Default.EEGNumChannels, bufferSizeSeconds, Convert.ToInt32(Properties.Settings.Default.EEGSamplingRate * (ADCPollingPeriodSamples / Properties.Settings.Default.RawSampleFrequency)), 1); } //6. Auxiliary analog data if (Properties.Settings.Default.useAuxAnalogInput) { auxAnalogSrv = new RawDataSrv( Properties.Settings.Default.RawSampleFrequency, Properties.Settings.Default.auxAnalogInChan.Count, bufferSizeSeconds, ADCPollingPeriodSamples, 1); } //7. Spike data, always available spikeSrv = new EventDataSrv <SpikeEvent>( Properties.Settings.Default.RawSampleFrequency, bufferSizeSeconds, ADCPollingPeriodSamples, Properties.Settings.Default.numSpikeTasks, spikeLag, Convert.ToInt32(Properties.Settings.Default.NumChannels)); //8. Auxiliary Digital data if (Properties.Settings.Default.useAuxDigitalInput) { auxDigitalSrv = new EventDataSrv <DigitalPortEvent>( Properties.Settings.Default.RawSampleFrequency, bufferSizeSeconds, ADCPollingPeriodSamples, 1, 0, 32); } //9. Stimulus data if (Properties.Settings.Default.RecordStimTimes) { stimSrv = new EventDataSrv <ElectricalStimEvent>( Properties.Settings.Default.RawSampleFrequency, bufferSizeSeconds, ADCPollingPeriodSamples, 1, 0, 0); } }
internal void UpdateScatterGraph(RawDataSrv analogDataServer, double requestedHistorySec, double peakVoltage, double shift) { // One over samplefreq double oneOverSampleFreq = 1 / analogDataServer.SampleFrequencyHz; // First retrieve the data thats in the range of the users request ulong[] availableDataRange = analogDataServer.EstimateAvailableTimeRange(); // Plot bound settings ulong historySamples = (ulong)(analogDataServer.SampleFrequencyHz * requestedHistorySec); double minUpdateTimeSec = 0.05; //seconds int downSampleFactor = (int)(historySamples/_numSampToPlot); if (historySamples < _numSampToPlot) { downSampleFactor = 1; numSampToPlot = historySamples; } else { numSampToPlot = _numSampToPlot; } int newDataLength; if ((availableDataRange[1]-lastSampleRead)*oneOverSampleFreq > minUpdateTimeSec) { // x-data storage double[] xDat; int k = 0; // Get data in requested history RawMultiChannelBuffer analogData; if (historySamples > availableDataRange[1]) { analogData = analogDataServer.ReadFromBuffer(0, availableDataRange[1]); newDataLength = analogData.Buffer[0].Length / downSampleFactor; // Make X data, always 0 to whatever the plot width is xDat = new double[newDataLength]; for (int j = 0; j < xDat.Length; ++j) { xDat[j] = k * oneOverSampleFreq; k = k + downSampleFactor; } } else if(availableDataRange[1] - lastSampleRead > historySamples) { analogData = analogDataServer.ReadFromBuffer(availableDataRange[1] - historySamples, availableDataRange[1]); newDataLength = analogData.Buffer[0].Length / downSampleFactor; // Make X data, always 0 to whatever the plot width is xDat = new double[numSampToPlot]; for (int j = 0; j < xDat.Length; ++j) { xDat[j] = k * oneOverSampleFreq; k = k + downSampleFactor; } } else { analogData = analogDataServer.ReadFromBuffer(lastSampleRead, availableDataRange[1]); newDataLength = analogData.Buffer[0].Length / downSampleFactor; // Make X data, always 0 to whatever the plot width is xDat = new double[numSampToPlot]; for (int j = 0; j < xDat.Length; ++j) { xDat[j] = k * oneOverSampleFreq; k = k + downSampleFactor; } } // Update last sample read lastSampleRead = analogData.StartAndEndSample[1]; // Get plot range Range plotYRange = new Range(-peakVoltage + shift, peakVoltage + shift); Range plotXRange = new Range(0, xDat[xDat.Length-1]); // Update the scatter plot for (int i = 0; i < analogScatterGraph.Plots.Count; ++i) { double[] yDatTmp = analogData.Buffer[i]; double[] yDatDS = new double[newDataLength]; // Make y data k = 0; for (int j = 0; j < newDataLength; ++j) { yDatDS[j] = yDatTmp[k]; k = k + downSampleFactor; } // Append new data to old data as needed double[] yDat = new double[xDat.Length]; double[] oldYDat = analogScatterGraph.Plots[i].GetYData(); k = xDat.Length; for (int j = 1; j <= xDat.Length; ++j) { --k; if (j <= yDatDS.Length) yDat[k] = yDatDS[yDatDS.Length - j]; else if (oldYDat.Length + yDatDS.Length - j >= 0) yDat[k] = oldYDat[oldYDat.Length + yDatDS.Length - j]; else yDat[k] = 0.0; } // set plot range analogScatterGraph.Plots[i].YAxis.Range = plotYRange; analogScatterGraph.Plots[i].XAxis.Range = plotXRange; analogScatterGraph.Plots[i].PlotXYAppend(xDat,yDat); } } }