rawecgheader.cs

来自「ecg tool kit for medical image retrieval」· CS 代码 · 共 1,264 行 · 第 1/3 页

CS
1,264
字号
/***************************************************************************
Copyright 2004,2008, Thoraxcentrum, Erasmus MC, Rotterdam, The Netherlands

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

Written by Marcel de Wijs. Changed by Maarten van Ettinger.

****************************************************************************/
using System;
using System.Runtime.InteropServices;
using Communication.IO.Tools;
using ECGConversion.ECGDemographics;
using ECGConversion.ECGSignals;

namespace ECGConversion.RawFormat
{
    /// <summary>
    /// Summary description for RawECGHeader.
    /// </summary>
	public class RawECGHeader : IDemographic, ISignal
	{
		// static variables to read header
		public static byte ValueOfP = 0x50;
		public static byte ValueOfK = 0x4b;
		public static int HeaderSize = 512;
		//        private static int _HeadHeadPadding = 15;
		// format of header
		private byte _P;
		private byte _K;
		//        private byte _FileVersion;
		//        private byte _FileType;
		private short _HeaderSize;
		private uint _TotalFileSize;
		private byte _Day;
		private byte _Month;
		private short _Year;
		private byte _Hour;
		private byte _Min;
		private byte _Sec;
		private RawECGPatientId     _PatId      = new RawECGPatientId();
		private RawECGIdRecordInfo  _IdRecInfo  = new RawECGIdRecordInfo();
		private RawECGInfo          _ECGInfo    = new RawECGInfo();
		private RawECGRecordInfo    _RecInfo    = new RawECGRecordInfo();
        
		private LeadType[]          LeadConfiguration;
		/// <summary>
		/// Function to read header from buffer.
		/// </summary>
		/// <param name="buffer">buffer to read from</param>
		/// <param name="offset">position to start reading</param>
		/// <param name="littleEndian">true if little endian is used</param>
		/// <returns>0 on success</returns>
		public int Read(byte[] buffer, int offset, bool littleEndian)
		{
			if ((buffer == null)
			||	((offset + HeaderSize) > buffer.Length))
			{
				return 0x1;
			}
            
			if ((_P != ValueOfP)
			||	(_K != ValueOfK))
			{
				return 0x2;
			}

          
			_Day    =   (byte)System.DateTime.Now.Date.Day; 
			_Month  =   (byte)System.DateTime.Now.Date.Month;
			_Year   =   (short)System.DateTime.Now.Date.Year;
			_Hour   =   (byte)System.DateTime.Now.Date.Hour;
			_Min    =   (byte)System.DateTime.Now.Date.Minute;
			_Sec    =   (byte)System.DateTime.Now.Date.Second;

			_PatId.Read(buffer, offset, littleEndian); 
			_IdRecInfo.Read(buffer, offset, littleEndian); 
			_ECGInfo.Read(buffer, offset, littleEndian); 
			_RecInfo.Read(buffer, offset, littleEndian);

			return 0x0;
		}
		/// <summary>
		/// Function to write header into a buffer.
		/// </summary>
		/// <param name="buffer">buffer to write in</param>
		/// <param name="littleEndian">true if little endian is used</param>
		/// <returns>0 on success</returns>
		public int Write(out byte[] buffer, bool littleEndian)
		{
			buffer = new byte[_HeaderSize];
			int err = Write(buffer, 0, littleEndian);
			if (err != 0)
			{
				buffer = null;
			}
			return err;
		}
		/// <summary>
		/// Function to write header into a buffer.
		/// </summary>
		/// <param name="buffer">buffer to write in</param>
		/// <param name="offset">position to start writing</param>
		/// <param name="littleEndian">true if little endian is used</param>
		/// <returns>0 on success</returns>
		public int Write(byte[] buffer, int offset, bool littleEndian)
		{
			if (!Works())
			{
				return 0x1;
			}

			if ((buffer == null)
			||	((offset + _HeaderSize) > buffer.Length))
			{
				return 0x2;
			}

			_HeaderSize = (short) HeaderSize;
			_TotalFileSize = (uint) (((_ECGInfo.NrOfLeads * _ECGInfo.NrECGSamples) << 1) );

			return 0;
		}
		/// <summary>
		/// Function to anonymous the header.
		/// </summary>
		/// <param name="type">character to use for anonymous</param>
		public void Anonymous(byte type)
		{
			// Empty id, lastname and firstname.
			BytesTool.emptyBuffer(_PatId.Id, 0, BytesTool.stringLength(_PatId.Id, 0, RawECGPatientId.MaxIdLen), type);
			BytesTool.emptyBuffer(_PatId.LastName, 0, BytesTool.stringLength(_PatId.LastName, 0, RawECGPatientId.MaxNameLen), type);
			BytesTool.emptyBuffer(_PatId.FirstName, 0, BytesTool.stringLength(_PatId.FirstName, 0, RawECGPatientId.MaxNameLen), type);
			// Setting date to first of january.
			_PatId.BirthDate[4] = (byte) '0';
			_PatId.BirthDate[5] = (byte) '1';
			_PatId.BirthDate[6] = (byte) '0';
			_PatId.BirthDate[7] = (byte) '1';
			_PatId.BirthDate[8] = 0;
		}
		/// <summary>
		/// Function to empty header.
		/// </summary>
		public void Empty()
		{
			_P = ValueOfP;
			_K = ValueOfK;
			//            _FileVersion = 0x16;
			//            _FileType = 12;
			_HeaderSize = (short) HeaderSize;
			_TotalFileSize = 0;
			_Day = 0;
			_Min = 0;
			_Year = 0;
			_Hour = 0;
			_Min = 0;
			_Sec = 0;
			_PatId.Empty();
			_IdRecInfo.Empty();
			_RecInfo.Empty();
			_ECGInfo.Empty();
			if ( LeadConfiguration == null)
			{
				LeadConfiguration = new LeadType[8];
				LeadConfiguration[0] = LeadType.I;
				LeadConfiguration[1] = LeadType.II;
				LeadConfiguration[2] = LeadType.V1;
				LeadConfiguration[3] = LeadType.V2;
				LeadConfiguration[4] = LeadType.V3;
				LeadConfiguration[5] = LeadType.V4;
				LeadConfiguration[6] = LeadType.V5;
				LeadConfiguration[7] = LeadType.V6;
			}
		}
		/// <summary>
		/// Function to check if header makes sense.
		/// </summary>
		/// <returns></returns>
		public bool Works()
		{
			return ((_P == ValueOfP)
				&&	(_K == ValueOfK)
				&&	(_HeaderSize == HeaderSize)
				&&	(_PatId.Id != null)
				&&	(_PatId.Id[0] != 0x00)
				&&	(_ECGInfo.ECGLSBPerMV > 0)
				&&	(_ECGInfo.ECGSampFreq > 0)
				&&	(_ECGInfo.NrECGSamples > 0)
				&&	(_ECGInfo.NrOfLeads > 0)
				&&	(_ECGInfo.NrOfLeads <= RawECGInfo.MaxNrLeads));
		}
		/// <summary>
		/// Function to get number of leads.
		/// </summary>
		/// <returns>number of leads</returns>
		public int getNrLeads()
		{
			if (Works())
			{
				return _ECGInfo.NrOfLeads;
			}
			return 0;
		}
		/// <summary>
		/// Function to get number of samples per lead.
		/// </summary>
		/// <returns>number of samples per lead</returns>
		public uint getNrSamplesPerLead()
		{
			if (Works())
			{
				return _ECGInfo.NrECGSamples;
			}
			return 0;
		}

		public short getLSBPerMV()
		{
			if (Works())
			{
				return _ECGInfo.ECGLSBPerMV;
			}
			return 0;
		}

		public void setNrLeads(int nNrLeads)
		{
			_ECGInfo.NrOfLeads = (short)nNrLeads;
		}
		/// <summary>
		/// Function to get number of samples per lead.
		/// </summary>
		/// <returns>number of samples per lead</returns>
		public void setNrSamplesPerLead(int nNrSamplesPerLead)
		{
			_ECGInfo.NrECGSamples = (uint)nNrSamplesPerLead;
		}

		public short getSampleRate()
		{
			if (Works())
			{
				return _ECGInfo.ECGSampFreq;
			}
			return 0;
		}
		public void setSampleRate(int nECGSampeFreq)
		{
			_ECGInfo.ECGSampFreq = (short)nECGSampeFreq;
		}

		public void setLSBPerMV(int nLSBPerMV)
		{
			_ECGInfo.ECGLSBPerMV = (short)nLSBPerMV;
		}

		public void setLeadConfiguration(string[] myLeadConfig)
		{
			if (myLeadConfig.Length != LeadConfiguration.Length)
			{
				LeadConfiguration = new LeadType[myLeadConfig.Length];
			}

			for (int i=0; i<myLeadConfig.Length; i++)
			{
				LeadConfiguration[i] = (LeadType)Enum.Parse(typeof(LeadType),myLeadConfig[i],true);
			}
		}

		/// <summary>
		/// Function to get the length of the ecg data according to the Header.
		/// </summary>
		/// <returns>length of ecg data</returns>
		public uint getDataLength()
		{
			if (Works())
			{
				return (uint) (_ECGInfo.NrECGSamples * _ECGInfo.NrOfLeads * Marshal.SizeOf(typeof(short)));
			}
			return 0;
		}
		/// <summary>
		/// Function to get if data is stored little endian or not.
		/// </summary>
		/// <returns>true if little endian</returns>
		public bool isLittleEndian()
		{
			return true;
		}
		/// <summary>
		/// Class containing patient Id.
		/// </summary>
		public class RawECGPatientId
		{
			// static variables for definition of structure.
			public static int Size = 80;
			public static int Padding = 8;
			public static int MaxIdLen = 21;
			public static int MaxNameLen = 23;
			public static int MaxDateLen = 9;
			// structure of data.
			public short IdFormat;
			public byte[] Id = new byte[MaxIdLen];
			public byte[] LastName = new byte[MaxNameLen];
			public byte[] FirstName = new byte[MaxNameLen];
			public byte[] BirthDate = new byte[MaxDateLen];
			public byte Sex;
			public byte Race;
			/// <summary>
			/// Function to read patient id from buffer.
			/// </summary>
			/// <param name="buffer">buffer to read from</param>
			/// <param name="offset">position to start reading</param>
			/// <param name="littleEndian">true if little endian is used</param>
			/// <returns>0 on success</returns>
			public int Read(byte[] buffer, int offset, bool littleEndian)
			{
				string name;

				IdFormat=0;

				string id = "1234567";
				BytesTool.writeString(id,Id, 0, RawECGPatientId.MaxNameLen);

				name = "unknown";
				BytesTool.writeString(name, LastName, 0, RawECGPatientId.MaxNameLen);
				BytesTool.writeString(name, FirstName, 0, RawECGPatientId.MaxNameLen);

				Date myDate = new Date(1901,1,1); 
				BytesTool.writeString(myDate.Year.ToString("d4"), BirthDate, 0, 5);
				BytesTool.writeString(myDate.Month.ToString("d2"), BirthDate, 4, 3);
				BytesTool.writeString(myDate.Day.ToString("d2"), BirthDate, 6, 3);

				Sex = (byte)0;

				Race = (byte)0;

				return 0;
			}
			/// <summary>
			/// Function to write patient id into a buffer.
			/// </summary>
			/// <param name="buffer">buffer to write in</param>
			/// <param name="offset">position to start writing</param>
			/// <param name="littleEndian">true if little endian is used</param>
			/// <returns>0 on success</returns>
			public int Write(byte[] buffer, int offset, bool littleEndian)
			{
				// empty, shoudl nog be called
				throw new SystemException();
			}
			/// <summary>
			/// Function to empty header.
			/// </summary>
			public void Empty()
			{
				IdFormat = 0;
				Id = new byte[MaxIdLen];
				Id = System.Text.ASCIIEncoding.ASCII.GetBytes("1234567");
				LastName = new byte[MaxNameLen];
				FirstName = new byte[MaxNameLen];
				BirthDate = new byte[MaxDateLen];
				for (int loper=0;loper < MaxDateLen-1;loper++)
				{
					BirthDate[loper] = (byte) '0';
				}
				Sex = 0;
				Race = 0;
			}
		}
		/// <summary>
		/// Class containing Id record info.
		/// </summary>
		public class RawECGIdRecordInfo
		{
			// static variables for definition of structure.
			public static int Size = 22;
			public static int Padding = 10;
			public static int MaxNrDrugs = 2;
			public static int MaxNrClinClass = 2;
			// structure of data.
			public short AgeYears;
			public short AgeMonths;
			public short AgeDays;
			public short[] Drugs = new short[MaxNrDrugs];
			public short[] ClinClass = new short[MaxNrClinClass];
			public short Height;
			public short Weight;
			public short SysBP;
			public short DiaBP;
			/// <summary>
			/// Function to read id record info from buffer.
			/// </summary>
			/// <param name="buffer">buffer to read from</param>
			/// <param name="offset">position to start reading</param>
			/// <param name="littleEndian">true if little endian is used</param>
			/// <returns>0 on success</returns>
			public int Read(byte[] buffer, int offset, bool littleEndian)
			{
				// default applied
				AgeYears = 0;
				AgeMonths = 0;
				AgeDays = 0;

				for (int loper=0;loper < MaxNrDrugs;loper++)
				{
					Drugs[loper] = (short)0;
				}

				for (int loper=0;loper < MaxNrClinClass;loper++)
				{
					ClinClass[loper] = (short)0;
				}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?