public override void Process(Frame inputFrame) { base.Process(inputFrame); for (int i = 0; i < inputFrame.nsamples; i++) _output[i] += (Math.Abs(inputFrame.samples[i]) / (double)frameBlockSize); }
public override void Process(Frame inputFrame) { base.Process(inputFrame); if(_prevFrame!=null) { for (int i = 0; i < inputFrame.nsamples; i++) _output[i] = Math.Abs(inputFrame.samples[i]) - Math.Abs(_prevFrame.samples[i]); } _prevFrame=inputFrame; }
public override void Process(Frame inputFrame) { base.Process(inputFrame); if (_prevFrame != null) { for (int i = 0; i < inputFrame.nsamples; i++) if (((_prevFrame.samples[i] >= 0) && (inputFrame.samples[i] < 0)) || ((_prevFrame.samples[i] < 0) && (inputFrame.samples[i] >= 0))) _output[i]++; } _prevFrame = inputFrame; }
public override void Process(Frame inputFrame) { base.Process(inputFrame); double slope; if (_prevFrame != null && _prevPrevFrame!=null) { for (int i = 0; i < inputFrame.nsamples; i++) { slope = (float)((inputFrame.samples[i] - _prevFrame.samples[i]) / (inputFrame.timeIdx - _prevFrame.timeIdx)); if ((slope >= 0 && _prevSlopeArray[i] < 0) || (slope < 0 && _prevSlopeArray[i] >= 0)) _output[i]++; _prevSlopeArray[i] = slope; } } else if (_prevSlopeArray == null || _prevSlopeArray.Length < inputFrame.nsamples) _prevSlopeArray = new double[inputFrame.nsamples]; _prevPrevFrame = _prevFrame; _prevFrame = inputFrame; }
/// <summary> /// Process an input frame and updates the output. This method should be Invoked at the very beginning /// of any derived class. /// </summary> public virtual void Process(Frame inputFrame) { if (_output == null || output.Length!=inputFrame.nsamples) _output = new double[inputFrame.nsamples]; }
public void NewPacket(XDataPacket packet) { Byte[] buffer; double[] sample = new double[packet.nChannels]; Byte[] frame = new Byte[packet.frameSize]; UInt32 countvalue; float inputDifferentialVoltage = ADS1298DataQueue.Instance.posVoltage - ADS1298DataQueue.Instance.negVoltage; UInt32 powerOfResBits = (UInt32)(1 << packet.resolutionBits); Frame currentFrame; BlockingCollection<Object> queue = ADS1298DataQueue.Instance.queue; //Length of the moving average buffer used when correcting signal offset UInt32 correctLength = packet.sampleFreq/8; bool correctOffset = ADS1298DataQueue.Instance.correctOffset; if (correctOffset) { //Using an average array with 0.125 seconds of samples (packet.sampleFreq/8) if (_avgArray == null) _avgArray = new double[correctLength, packet.nChannels]; if (_avgValues == null) _avgValues = new double[packet.nChannels]; } if (queue.IsAddingCompleted) return; if (ADS1298DataQueue.Instance.paused) return; //We transform back the frame data into a byte array buffer = System.Convert.FromBase64String(packet.payload); if (packet.lastPacket == true) { //We have received a dummy packet indicating that there will be no more frame packets coming. //The current capture session has finished, but we only mark the queue as complete for adding //if the data acquisition is not paused. if (!ADS1298DataQueue.Instance.paused) queue.CompleteAdding(); return; } int temp; for (Int32 i = 0; i < packet.nFrames; i++) { Buffer.BlockCopy(buffer, (Int32) packet.frameSize * i, frame, 0, (Int32) packet.frameSize); countvalue = (UInt32)(frame[00]<<16|frame[01]<<8|frame[02]); int channel = 0; double min = 0; double max = 0; for (int j = 3; j <= frame.Length-3; j=j+3 ) { temp = (frame[j] << 24 | frame[j+1] << 16 | frame[j+2] << 8) / 256; //Experimenting with a moving average to detect the channel amplitude offset if (correctOffset) { /* _avgArray[avgPos, channel] = (double)temp / (double)correctLength; _avgValues[channel] = _avgValues[channel] + _avgArray[avgPos, channel] - _avgArray[(int)((avgPos + 1) % correctLength), channel]; */ _avgValues[channel] = _avgValues[channel] - _avgArray[avgPos, channel]; _avgArray[avgPos, channel] = (double)temp / (double)correctLength; _avgValues[channel] += _avgArray[avgPos, channel]; temp -= (int)_avgValues[channel]; } //End of the experiment sample[channel] = ((double)temp / (double)powerOfResBits) * inputDifferentialVoltage; if (channel == 0) { min = sample[channel]; max = sample[channel]; } else { if (sample[channel] < min) min = sample[channel]; else if (sample[channel] > max) max = sample[channel]; } channel++; } //This is only used when performing offset correction avgPos = (int)((avgPos + 1) % correctLength); currentFrame = new Frame(sample, ADS1298DataQueue.Instance.frameIdx, ADS1298DataQueue.Instance.timeIdx, min, max); ADS1298DataQueue.Instance.frameIdx++; ADS1298DataQueue.Instance.timeIdx = ADS1298DataQueue.Instance.frameIdx / (double)packet.sampleFreq; queue.Add(currentFrame); } }
/// <summary> /// Translates the recorded data inside the HDF5 file into a Recording object /// </summary> /// <param name="data"></param> /// <returns></returns> private void FillRecording(double[, ,] data, Recording recording, List<int> positionSelection, List<ScheduleItem> movCodes) { RecordingConfig recordingConfig = recording.parameters; double minVal, maxVal; int nMovs = data.GetLength(0); int nChannels = data.GetLength(1); int nSamples = data.GetLength(2); minVal = data[0, 0, 0]; maxVal = minVal; foreach (int i in positionSelection) { for (int j = 0; j < nChannels; j++) for (int k = 0; k < nSamples; k++) { if (data[i, j, k] < minVal) minVal = data[i, j, k]; if (data[i, j, k] > maxVal) maxVal = data[i, j, k]; } } recordingConfig.minVoltage = minVal; recordingConfig.maxVoltage = maxVal; int count = 0; foreach (int movIndex in positionSelection) { for (int sampleIndex = 0; sampleIndex < nSamples; sampleIndex++) { double min = 0; double max = 0; //Here we compose the frame double[] samples = new double[nChannels]; for (int channelIndex = 0; channelIndex < nChannels; channelIndex++) { samples[channelIndex] = data[movIndex, channelIndex, sampleIndex]; if (channelIndex == 0) { min = samples[channelIndex]; max = samples[channelIndex]; } else { if (samples[channelIndex] < min) min = samples[channelIndex]; else if (samples[channelIndex] > max) max = samples[channelIndex]; } } uint sequenceIdx = (uint)((count * nSamples) + sampleIndex); double timeIdx = sequenceIdx / (double)recordingConfig.sampleFreq; Frame newFrame = new Frame(samples, sequenceIdx, timeIdx, min, max); if (_version < 0) //We are reading a file exported form the BioPatRec samples. Rests are recorded but not //marked as movements, thus the movement at position 0 of the movement list is never //a rest. We change this to an MPTCE-friendly codification where 0 means rest { if (sampleIndex % (recordingConfig.sampleFreq * (recordingConfig.scheduleItemTime + _restTime)) < (recordingConfig.sampleFreq * recordingConfig.scheduleItemTime)) newFrame.movementCode = movCodes[movIndex].movementCode; else newFrame.movementCode = 0; } else //This is an MPTCE-generated file. Rests are always a movement, and the movement code for each //movement in movIndex is stored in the movSeq attribute newFrame.movementCode = (int)_movSeq[movIndex]; recording.data.Add(newFrame); } count++; } }
public override void Clear() { base.Clear(); _prevFrame = null; _prevPrevFrame = null; }
public void NewPacket(XDataPacket packet) { //Console.Out.Write("* "); Byte[] buffer; Int32 nFrames; double[] sample = new double[8]; Byte[] frame = new Byte[27]; UInt32 countvalue; Byte DATALENGTH = 27; float inputDifferentialVoltage = packet.inputDifferentialVoltagePositive - packet.inputDifferentialVoltageNegative; UInt32 powerOfResBits = (UInt32)(1 << packet.resolutionBits); Frame currentFrame; Console.Out.WriteLine("sampleFreq: {0}",packet.sampleFreq); Console.Out.WriteLine("payloadSize: {0}", packet.payloadSize); //We transform back the frame data into a byte array buffer = System.Convert.FromBase64String(packet.payload); nFrames = packet.payloadSize/DATALENGTH; //We should get DATALENGTH from the device model! for (Int32 i = 0; i < nFrames; i++) { Buffer.BlockCopy(buffer, DATALENGTH * i, frame, 0, DATALENGTH); //An unrolled loop to obtain the counter and float values for each frame countvalue = (UInt32)(frame[00]<<16|frame[01]<<8|frame[02]); sample[0]=frame[03]<<24|frame[04]<<16|frame[05]<<8; sample[0]=(sample[0]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[1]=frame[06]<<24|frame[07]<<16|frame[08]<<8; sample[1]=(sample[1]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[2]=frame[09]<<24|frame[10]<<16|frame[11]<<8; sample[2]=(sample[2]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[3]=frame[12]<<24|frame[13]<<16|frame[14]<<8; sample[3]=(sample[3]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[4]=frame[15]<<24|frame[16]<<16|frame[17]<<8; sample[4]=(sample[4]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[5]=frame[18]<<24|frame[19]<<16|frame[20]<<8; sample[5]=(sample[5]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[6]=frame[21]<<24|frame[22]<<16|frame[23]<<8; sample[6]=(sample[6]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); sample[7]=frame[24]<<24|frame[25]<<16|frame[26]<<8; sample[7]=(sample[7]/256)*inputDifferentialVoltage/(double)(powerOfResBits*packet.gain); currentFrame = new Frame(sample, countvalue, countvalue / (double) packet.sampleFreq,packet.inputDifferentialVoltageNegative,packet.inputDifferentialVoltagePositive); //DEBUG /* Console.Out.Write("{0} ", countvalue); Console.Out.Write("{0} ", sample[0]); Console.Out.Write("{0} ", sample[1]); Console.Out.Write("{0} ", sample[2]); Console.Out.Write("{0} ", sample[3]); Console.Out.Write("{0} ", sample[4]); Console.Out.Write("{0} ", sample[5]); Console.Out.Write("{0} ", sample[6]); Console.Out.Write("{0} ", sample[7]); */ //DEBUG/ } //DEBUG //And the, print out what we got formated by samples and fields /* Console.Out.WriteLine("Length of the recovered data: {0}", Buffer.ByteLength(buffer)); for (Int32 i = 0; i < frame.payloadSize; i++) { Console.Out.Write("{0} ", buffer[i]); } */ //DEBUG/ }
/// <summary> /// Returns an exact copy of the current Frame object /// </summary> /// <returns></returns> public Frame Clone() { Frame output; output = new Frame(samples,sequenceIdx,timeIdx,minVal,maxVal); return output; }