/// <summary> /// 计算AVG /// </summary> /// <param name="replayFile"></param> private void calcAVG(EDFFile edfFile) { // 1.添加AVG信道 EDFSignal signalAVG = new EDFSignal(); signalAVG.Label = "AVG"; signalAVG.IndexNumber = edfFile.Header.Signals.Count + 1; signalAVG.NumberOfSamplesPerDataRecord = edfFile.Header.Signals[0].NumberOfSamplesPerDataRecord; edfFile.Header.Signals.Add(signalAVG); // 2.添加AVG数据 for (int i = 0; i < edfFile.MyDataRecords.Count; i++) { MyEDFDataRecord record = edfFile.MyDataRecords[i]; float sum = 0f; float avg = 0f; for (int j = 0; j < record.Count; j++) { sum += record[j]; } avg = sum / record.Count; record.Add(avg); } }
/// <summary> /// 解析自定义的文件 --by zt /// </summary> /// <param name="sr"></param> private void parseMyDataRecordStream(StreamReader sr) { //set the seek position in the file stream to the beginning of the data records. sr.BaseStream.Seek((256 + this.Header.NumberOfSignalsInDataRecord * 256), SeekOrigin.Begin); int dataRecordSize = 0; foreach (EDFSignal signal in this.Header.Signals) { signal.SamplePeriodWithinDataRecord = (float)(this.Header.DurationOfDataRecordInSeconds / signal.NumberOfSamplesPerDataRecord); dataRecordSize += signal.NumberOfSamplesPerDataRecord; } byte[] dataRecordBytes = new byte[dataRecordSize * 3]; byte first00 = HexToByte("00")[0]; while (sr.BaseStream.Read(dataRecordBytes, 0, dataRecordSize * 3) > 0) { //EDFDataRecord dataRecord = new EDFDataRecord(); MyEDFDataRecord dataRecord = new MyEDFDataRecord(); int j = 0; int samplesWritten = 0; List <EDFSignal> signals = this.Header.Signals; #region 解析与edf格式相似的方式,以后可能会用到 --by zt //for (int i = 0; i < signals.Count; i++) //{ // List<float> samples = new List<float>(); // for (int l = 0; l < signals[i].NumberOfSamplesPerDataRecord; l++) // { // float refVoltage = signals[i].PhysicalMaximum; // //从dataRecordBytes中取3个字节 // byte[] temp = new byte[4] { dataRecordBytes[samplesWritten * 3 + 2], dataRecordBytes[samplesWritten * 3 + 1], dataRecordBytes[samplesWritten * 3], first00 }; // float value = (float)(BitConverter.ToInt32(temp, 0)); // if (value >= 0 && value <= Math.Pow(2, 23) - 1) // value = refVoltage * value / (float)(Math.Pow(2, 23) - 1); // else // value = refVoltage * ((value - (float)Math.Pow(2, 24)) / (float)(Math.Pow(2, 23) - 1)); // value = value / multiplyingPower; // samples.Add(value); // samplesWritten++; // } // dataRecord.Add(i.ToString(), samples); // //dataRecord.Add(value); // //dataRecord.Add(signal.IndexNumberWithLabel, value); // j++; //} #endregion 解析与edf格式相似的方式,以后可能会用到 --by zt foreach (EDFSignal signal in this.Header.Signals) { //List<float> samples = new List<float>(); //for (int l = 0; l < signal.NumberOfSamplesPerDataRecord; l++) //{ float refVoltage = signal.PhysicalMaximum; //从dataRecordBytes中取3个字节 byte[] temp = new byte[4] { dataRecordBytes[samplesWritten * 3 + 2], dataRecordBytes[samplesWritten * 3 + 1], dataRecordBytes[samplesWritten * 3], first00 }; float value = (float)(BitConverter.ToInt32(temp, 0)); if (value >= 0 && value <= Math.Pow(2, 23) - 1) { value = refVoltage * value / (float)(Math.Pow(2, 23) - 1); } else { value = refVoltage * ((value - (float)Math.Pow(2, 24)) / (float)(Math.Pow(2, 23) - 1)); } value = value / multiplyingPower; //samples.Add(value); samplesWritten++; //} //dataRecord.Add(signal.IndexNumberWithLabel, samples); dataRecord.Add(value); //dataRecord.Add(signal.IndexNumberWithLabel, value); j++; } _mydataRecords.Add(dataRecord); //_dataRecords.Add(dataRecord); } }
/// <summary> /// 解析BIO-NoDisplay格式的数据 /// </summary> /* * 笔记 StreamReader 以一种特定的编码输入字符 * */ private void parseDataRecordStreamByBIO(StreamReader sr) { // 先判断是否为NoDisplay格式 if (this._header.Signals[this._header.Signals.Count - 1].Label.EndsWith("NoRef", StringComparison.InvariantCultureIgnoreCase) == false) { throw new Exception("格式错误,请选择NoDisplay格式的数据。"); } // 跳过头文件 sr.BaseStream.Seek((256 + this.Header.NumberOfSignalsInDataRecord * 256), SeekOrigin.Begin); // TODO 20170626 暂时先用旧逻辑试试 #region 旧逻辑 // 计算每个信道的采样周期和总时长 int dataRecordSize = 0; foreach (EDFSignal signal in this.Header.Signals) { signal.SamplePeriodWithinDataRecord = (float)(this.Header.DurationOfDataRecordInSeconds / signal.NumberOfSamplesPerDataRecord); dataRecordSize += signal.NumberOfSamplesPerDataRecord; } // 移除最后一个注解通道,不滤波和画图(放在此处移除,是为了解析每个数据块和每个通道的字节数正确) - add by lzy 20170502 // TODO 移除后少个EKG通道 20170614 // this.Header.Signals.RemoveAt(this.Header.Signals.Count - 1); byte[] dataRecordBytes = new byte[dataRecordSize * 2]; List <MyEDFDataRecord> myDataRecordList = this._mydataRecords; if (myDataRecordList == null) { myDataRecordList = new List <MyEDFDataRecord>(); this._mydataRecords = myDataRecordList; } // 每次读出一秒内的20个通道的数据 while (sr.BaseStream.Read(dataRecordBytes, 0, dataRecordSize * 2) > 0) { // 每个时间点的全部通道的数据 MyEDFDataRecord myDataRecord = new MyEDFDataRecord(); int signalIndex = 0; int samplesWritten = 0; // 一秒内的全部通道的数据,一维索引为通道数,二维索引为位置 List <List <float> > samplesList = new List <List <float> >(); foreach (EDFSignal signal in this.Header.Signals) { float refVoltage = signal.PhysicalMaximum; // 一秒内一个通道内的数据 List <float> samples = new List <float>(); for (int l = 0; l < signal.NumberOfSamplesPerDataRecord; l++) { float value = (float)BitConverter.ToInt16(dataRecordBytes, (samplesWritten * 2)); if (this.Header.Version.Equals(NEURO_BOND_FLAG)) { if (value >= 0 && value <= Math.Pow(2, 15) - 1) { value = refVoltage * value / (float)(Math.Pow(2, 15) - 1); } else { //value = refVoltage * ((value - (float)Math.Pow(2, 20)) / (float)(Math.Pow(2, 19) - 1)); value = refVoltage * value / (float)Math.Pow(2, 15); } } // value /= multiplyingPower; samples.Add(value); samplesWritten++; } signalIndex++; samplesList.Add(samples); } // 把一秒内的全部通道的数据存入myDataRecordList int samplingRate = this.Header.Signals[0].NumberOfSamplesPerDataRecord; // 采样率,即每秒多少点 for (int i = 0; i < samplingRate; i++) { MyEDFDataRecord myEDFDataRecord = new MyEDFDataRecord(); for (int j = 0; j < samplesList.Count; j++) { if (i > samplesList[j].Count - 1) { continue; } float value = samplesList[j][i]; myEDFDataRecord.Add(value); } this._mydataRecords.Add(myEDFDataRecord); } } #endregion 旧逻辑 }
/// <summary> /// 解析edf数据到edfx中 add by lzy 20170427 /// </summary> /// <param name="sr"></param> private void parseDataRecordStream2(StreamReader sr) { //set the seek position in the file stream to the beginning of the data records. //设置当前文件流 开始读取的位置 /*sr.BaseStream.Seek(偏移量,开始位置)*/ sr.BaseStream.Seek((256 + this.Header.NumberOfSignalsInDataRecord * 256), SeekOrigin.Begin); int dataRecordSize = 0; //遍历头文件信号 foreach (EDFSignal signal in this.Header.Signals) { //数据采样周期= 采样频率 / 每个记录的样本数 signal.SamplePeriodWithinDataRecord = (float)(this.Header.DurationOfDataRecordInSeconds / signal.NumberOfSamplesPerDataRecord); dataRecordSize += signal.NumberOfSamplesPerDataRecord; //数据记录长度+=每条记录样本数 } // 移除最后一个注解通道,不滤波和画图(放在此处移除,是为了解析每个数据块和每个通道的字节数正确) - add by lzy 20170502 // TODO 移除后少个EKG通道 20170614 // this.Header.Signals.RemoveAt(this.Header.Signals.Count - 1); byte[] dataRecordBytes = new byte[dataRecordSize * 2]; List <MyEDFDataRecord> myDataRecordList = this._mydataRecords; if (myDataRecordList == null) { myDataRecordList = new List <MyEDFDataRecord>(); this._mydataRecords = myDataRecordList; } // 每次读出一秒内的20个通道的数据 while (sr.BaseStream.Read(dataRecordBytes, 0, dataRecordSize * 2) > 0) { // 每个时间点的全部通道的数据 MyEDFDataRecord myDataRecord = new MyEDFDataRecord(); int signalIndex = 0; int samplesWritten = 0; // 一秒内的全部通道的数据,一维索引为通道数,二维索引为位置 List <List <float> > samplesList = new List <List <float> >(); foreach (EDFSignal signal in this.Header.Signals) { float refVoltage = signal.PhysicalMaximum;//物理信号最大量 // 一秒内一个通道内的数据 List <float> samples = new List <float>(); for (int l = 0; l < signal.NumberOfSamplesPerDataRecord; l++) { float value = (float)BitConverter.ToInt16(dataRecordBytes, (samplesWritten * 2)); if (this.Header.Version.Equals(NEURO_BOND_FLAG)) { if (value >= 0 && value <= Math.Pow(2, 15) - 1) { value = refVoltage * value / (float)(Math.Pow(2, 15) - 1); } else { //value = refVoltage * ((value - (float)Math.Pow(2, 20)) / (float)(Math.Pow(2, 19) - 1)); value = refVoltage * value / (float)Math.Pow(2, 15); } } // value /= multiplyingPower; samples.Add(value); samplesWritten++; } signalIndex++; samplesList.Add(samples); } // 把一秒内的全部通道的数据存入myDataRecordList int samplingRate = this.Header.Signals[0].NumberOfSamplesPerDataRecord; // 采样率,即每秒多少点 for (int i = 0; i < samplingRate; i++) { MyEDFDataRecord myEDFDataRecord = new MyEDFDataRecord(); for (int j = 0; j < samplesList.Count; j++) { if (i > samplesList[j].Count - 1) { continue; } float value = samplesList[j][i]; myEDFDataRecord.Add(value); } this._mydataRecords.Add(myEDFDataRecord); } } }
/// <summary> /// 解析EDF数据到EDFX中 /// </summary> /// <param name="sr"></param> private void parseDataRecordStream2(StreamReader sr) { //set the seek position in the file stream to the beginning of the data records. //设置当前文件流 开始读取的位置 /*sr.BaseStream.Seek(偏移量,开始位置)*/ sr.BaseStream.Seek((256 + this.Header.NumberOfSignalsInDataRecord * 256), SeekOrigin.Begin); int dataRecordSize = 0; //遍历头文件信号 int count; Console.WriteLine("信号长度:" + this.Header.Signals.Count()); foreach (EDFSignal signal in this.Header.Signals) { //数据记录中的采样周期 = 数据记录秒的持续时间 / 每个数据记录的样本数 signal.SamplePeriodWithinDataRecord = (float)(this.Header.DurationOfDataRecordInSeconds / signal.NumberOfSamplesPerDataRecord); //Console.WriteLine($"数据记录中的采样周期={signal.SamplePeriodWithinDataRecord}={this.Header.DurationOfDataRecordInSeconds}/{signal.NumberOfSamplesPerDataRecord}"); //Console.WriteLine($"数据记录长度={dataRecordSize}+{signal.NumberOfSamplesPerDataRecord}={signal.NumberOfSamplesPerDataRecord+dataRecordSize}\n"); dataRecordSize += signal.NumberOfSamplesPerDataRecord; //数据记录长度+=每条记录样本数 } // 移除最后一个注解通道,不滤波和画图(放在此处移除,是为了解析每个数据块和每个通道的字节数正确) - add by lzy 20170502 // TODO 移除后少个EKG通道 20170614 // this.Header.Signals.RemoveAt(this.Header.Signals.Count - 1); //记录数据字节数组长度为 33*256*2 ///<summary> ///j录数据字节数组长度 ///</summary> byte[] dataRecordBytes = new byte[dataRecordSize * 2]; //自定义数据列表 List <MyEDFDataRecord> myDataRecordList = this._mydataRecords; //如果自定义数据列表为空 if (myDataRecordList == null) { //实例化自定义记录数据 myDataRecordList = new List <MyEDFDataRecord>(); this._mydataRecords = myDataRecordList; } // 每次读出一秒内的20个通道的数据 int a = 0; while (sr.BaseStream.Read(dataRecordBytes, 0, dataRecordSize * 2) > 0) { a++; //Console.Write($"[{a}]当前基础流位置:{sr.BaseStream.Read(dataRecordBytes, 0, dataRecordSize * 2)}"); // 每个时间点的全部通道的数据 MyEDFDataRecord myDataRecord = new MyEDFDataRecord(); int signalIndex = 0; int samplesWritten = 0; // 一秒内的全部通道的数据,一维索引为通道数,二维索引为位置 List <List <float> > samplesList = new List <List <float> >(); String str = ""; foreach (EDFSignal signal in this.Header.Signals) { float refVoltage = signal.PhysicalMaximum;//物理信号最大量(用来计算值) // 一秒内一个通道内的数据 List <float> samples = new List <float>(); //数据样本 str += $"[{a}]当前记录样本数[{signal.NumberOfSamplesPerDataRecord}] "; for (int l = 0; l < signal.NumberOfSamplesPerDataRecord; l++) { float value = (float)BitConverter.ToInt16(dataRecordBytes, (samplesWritten * 2)); //str += $"{samplesWritten * 2} "; /*手环模式*/ if (this.Header.Version.Equals(NEURO_BOND_FLAG)) { if (value >= 0 && value <= Math.Pow(2, 15) - 1) { value = refVoltage * value / (float)(Math.Pow(2, 15) - 1); } else { //value = refVoltage * ((value - (float)Math.Pow(2, 20)) / (float)(Math.Pow(2, 19) - 1)); value = refVoltage * value / (float)Math.Pow(2, 15); } } // value /= multiplyingPower; samples.Add(value); //str += $"{value} "; samplesWritten++; } str += "\n"; signalIndex++; samplesList.Add(samples);//往数据集里添加数据 } str += "\n\n"; //Console.WriteLine(str); // 把一秒内的全部通道的数据存入myDataRecordList int samplingRate = this.Header.Signals[0].NumberOfSamplesPerDataRecord; // 采样率,即每秒多少点 for (int i = 0; i < samplingRate; i++) { MyEDFDataRecord myEDFDataRecord = new MyEDFDataRecord(); for (int j = 0; j < samplesList.Count; j++) { if (i > samplesList[j].Count - 1) { continue; } float value = samplesList[j][i]; myEDFDataRecord.Add(value); } this._mydataRecords.Add(myEDFDataRecord); } } }