zoukankan      html  css  js  c++  java
  • C#读取横河WVF数据文件

    横河wvf型数据,分别保存在hdr(数据信息文件)和wvf(数据文件)两个文件中。

    其中HDR文件格式及参数可以参考: http://www.yokogawa.com/jp-ymi/tm/TI/TIdoc/TI700021.pdf

    1.保存hdr中数据信息的结构体

    View Code
    //.hdr文件的wvf文件信息struct
    public struct WVFInfo
    {
        public string FileName;
        public string FormatVersion;
        public string Model;
        public WVFEndianType Endian;
        public string DataFormat;
        public int GroupNumber;
        public int TraceTotalNumber;
        public int DataOffset;
        public List<WVFGroup> Groups;
    }
    
    //wvf group struct
    public struct WVFGroup
    {
        public int TraceNumber;
        public int BlockNumber;
    
        //Traces
        public List<string> TraceName;
        public List<int> BlockSize;
        public List<double> VResolution;
        public List<double> VOffset;
        public List<WVFByteFormatType> VDataTypeByteFormat;
        public List<int> VDataTypeByteNumber;
        public List<string> VUnit;
        public List<string> VPlusOverData;
        public List<string> VMinusOverData;
        public List<double> VIllegalData;
        public List<double> VMaxData;
        public List<double> VMinData;
        public List<double> HResolution;
        public List<double> HOffset;
        public List<string> HUnit;
    
        //currently only support 1 block
        public List<string> Date;
        public List<string> Time;
        public List<List<double>> TValues;
        public List<List<double>> YValues;
    }
    
    //wvf文件的数据格式struct
    public enum WVFByteFormatType
    {
        IS = 0, //int
        IU = 1, //unsigned int
        FS = 2, //float
    }
    
    //wvf文件的数据大小端struct
    public enum WVFEndianType
    {
        Big = 0, //Big Endian
        Little = 1 //Little Endian
    }

    2.读取hdr时会用到的字符串操作函数

    View Code
    string fileparse(string keyword, string text)
    {
        string value = "";
        int indexStart = text.IndexOf(keyword);
    
    
        if (indexStart < 0)
        {
            Console.WriteLine("Could not find " + keyword + " entry in the file");
        }
        else
        {
            int indexEnd = text.Substring(indexStart).IndexOf("\r\n");
            string line = text.Substring(indexStart, indexEnd).Trim();
            value = line.Replace(keyword, " ").Trim();
        }
    
        return value;
    }
    
    List<string> stringparse(string str)
    {
        string[] args = str.Trim().Split(' ');
        List<string> list = new List<string>();
    
        foreach (string arg in args)
        {
            if (arg.Trim().Length != 0)
            {
                list.Add(arg);
            }
        }
    
        return list;
    }

    3. 读取hdr文件的函数

    View Code
    //read header .hdr file
    void ReadHDR(string path)
    {
        string content = File.ReadAllText(path);
    
        info.FileName = path.Substring(0, path.LastIndexOf('.'));
        info.FormatVersion = fileparse("FormatVersion", content);
        info.Model = fileparse("Model", content);
        info.DataFormat = fileparse("DataFormat", content);
        info.GroupNumber = Convert.ToInt32(fileparse("GroupNumber", content));
        info.TraceTotalNumber = Convert.ToInt32(fileparse("TraceTotalNumber", content));
        info.DataOffset = Convert.ToInt32(fileparse("DataOffset", content));
        info.Endian = (fileparse("Endian", content) == "Big") ? WVFEndianType.Big : WVFEndianType.Little;
        info.Groups = new List<WVFGroup>();
    
        for (int i = 0; i < Info.GroupNumber; i++)
        {
            //Group
            WVFGroup group = new WVFGroup();
            int groupIndex = content.IndexOf("$Group" + (i+1).ToString());
            string groupContent = content.Substring(groupIndex);
            group.TraceNumber = Convert.ToInt32(fileparse("TraceNumber", groupContent));
            group.BlockNumber = Convert.ToInt32(fileparse("BlockNumber", groupContent));
            
    
            //Traces
            group.TraceName = stringparse(fileparse("TraceName", groupContent));
            group.BlockSize = stringparse(fileparse("BlockSize", groupContent)).ConvertAll<int>(x => Convert.ToInt32(x));
            group.VResolution = stringparse(fileparse("VResolution", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));
            group.VOffset = stringparse(fileparse("VOffset", groupContent)).ConvertAll<double>(x=>Convert.ToDouble(x));
            
            List<string> vDataType = stringparse(fileparse("VDataType", groupContent));
            group.VDataTypeByteFormat = new List<WVFByteFormatType>();
            group.VDataTypeByteNumber = new List<int>();
    
            /*
            % VDataType
            % ISn : n-byte signed integer
            % IUn : n-byte unsigned integer
            % FSn : n-byte signed real
            % FUn : n-byte unsigned real
            % Bm : m-byte logical data
            */
            foreach (string dt in vDataType)
            {
                int num = 0;
                switch (dt[0])
                {
                    case 'I':  //integer numbers
                        switch (dt[1])
                        {
                            case 'S':
                                group.VDataTypeByteNumber.Add(Convert.ToInt32(dt.Substring(2)));
                                group.VDataTypeByteFormat.Add(WVFByteFormatType.IS);
                                break;
                            case 'U':
                                group.VDataTypeByteNumber.Add(Convert.ToInt32(dt.Substring(2)));
                                group.VDataTypeByteFormat.Add(WVFByteFormatType.IU);
                                break;
                            default:
                                group.VDataTypeByteNumber.Add(0);
                                group.VDataTypeByteFormat.Add(WVFByteFormatType.IS);
                                break;
                        }
                        break;
                    case 'F':   //real numbers
                        switch (dt[1])
                        {
                            case 'S':
                                group.VDataTypeByteNumber.Add(Convert.ToInt32(dt.Substring(2)));
                                group.VDataTypeByteFormat.Add(WVFByteFormatType.FS);
                                break;
                            default:
                                group.VDataTypeByteNumber.Add(0);
                                group.VDataTypeByteFormat.Add(WVFByteFormatType.FS);
                                break;
                        }
                        break;
                    default:
                        group.VDataTypeByteNumber.Add(0);
                        group.VDataTypeByteFormat.Add(WVFByteFormatType.IS);
                        break;
                }
    
            }
    
            group.VUnit = stringparse(fileparse("VUnit", groupContent));
            group.VPlusOverData = stringparse(fileparse("VPlusOverData", groupContent));
            group.VMinusOverData = stringparse(fileparse("VMinusOverData", groupContent));
            group.VIllegalData = stringparse(fileparse("VIllegalData", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));
            group.VMaxData = stringparse(fileparse("VMaxData", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));
            group.VMinData = stringparse(fileparse("VMinData", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));
            group.HResolution = stringparse(fileparse("HResolution", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));
            group.HOffset = stringparse(fileparse("HOffset", groupContent)).ConvertAll<double>(x => Convert.ToDouble(x));
            group.HUnit = stringparse(fileparse("HUnit", groupContent));
            group.Date = stringparse(fileparse("Date", groupContent));
            group.Time = stringparse(fileparse("Time", groupContent));
            group.TValues = new List<List<double>>();
            group.YValues = new List<List<double>>();
    
            Info.Groups.Add(group);
        }
    
    }

    4. 读取wvf文件的函数

    View Code
    //read data .wvf file
    void ReadWVF(int groupIndex = 0, int traceIndex = 0, int blockIndex = 0)
    {
        // Offset at beginning of binary file
        int offset = Info.DataOffset;
    
        // first for all groups before the selected group
        for (int i = 0; i < groupIndex; i++)
        {
            // for all traces and blocks in these groups...
            for (int j = 0; j < Info.Groups[i].TraceNumber; j++)
            {
                // add the offsets of all traces...
                offset += Info.Groups[i].BlockSize[j] * Info.Groups[i].BlockNumber * Info.Groups[i].VDataTypeByteNumber[j];
            }
        }
    
    
        // File Format Trace or Block saves traces and blocks in different
        // sequences:
        // Trace : Group1,Trace1,Block1, Group1,Trace1,Block2, ..., Group1,Trace1,BlockN, ..., Group1,Trace2,Block1, ..., Group2,Trace1,Block1, ..., GroupN,TraceN,BlockN (each block for a specific waveform)
        // Block : Group1,Trace1,Block1, Group1,Trace2,Block1, ..., Group1,TraceN,Block1, ..., Group1,Trace1,Block2, ..., Group2,Trace1,Block1, ..., GroupN,TraceN,BlockN (each block for a specific time interval).
        if (Info.DataFormat == "Trace")
        {
            //trace format:
            //%... add offsets of the traces before the selected trace in the selected group
            for (int i = 0; i < traceIndex; i++)
            {
                offset += Info.Groups[groupIndex].BlockSize[i] * Info.Groups[groupIndex].BlockNumber * Info.Groups[groupIndex].VDataTypeByteNumber[i];
            }
            //... and finally add offsets of the blocks in the selected trace in the selected group before the selected block
            offset += Info.Groups[groupIndex].BlockSize[traceIndex] * blockIndex * Info.Groups[groupIndex].VDataTypeByteNumber[traceIndex]; ;
        }
        else
        {
            //block format:
            //%... add offsets of the blocks before the selected block in the selected group
            for (int i = 0; i < blockIndex; i++)
            {
                for (int j = 0; j < Info.Groups[groupIndex].TraceNumber; j++)
                {
                    offset += Info.Groups[groupIndex].BlockSize[j] * Info.Groups[groupIndex].VDataTypeByteNumber[j];
                }
            }
            //... and finally add offsets of the traces in the selected block in the selected group before the selected trace
            for (int i = 0; i < traceIndex; i++)
            {
                offset += Info.Groups[groupIndex].BlockSize[i] * Info.Groups[groupIndex].VDataTypeByteNumber[i];
            }
        }
        
        fs.Seek(offset, SeekOrigin.Begin);
    
        //number of data points stored in the selected trace in the file
        int nop = Info.Groups[groupIndex].BlockSize[traceIndex];
        
        WVFByteFormatType byteFormat = Info.Groups[groupIndex].VDataTypeByteFormat[traceIndex];
        int byteNum = Info.Groups[groupIndex].VDataTypeByteNumber[traceIndex];
        List<double> listY = new List<double>();
        List<double> listT = new List<double>();
        
        //read data values
        for (int i = 0; i < nop; i++)
        {
            byte[] bVal = reader.ReadBytes(byteNum);
            double dVal = 0;
    
            switch (byteFormat)
            {
                case WVFByteFormatType.IS:
                    switch (byteNum)
                    {
                        case 2:
                            switch (Info.Endian)
                            {
                                case WVFEndianType.Big:
                                    dVal = BitConverter.ToInt16(bVal.Reverse().ToArray(), 0);
                                    break;
                                default:
                                    dVal = BitConverter.ToInt16(bVal, 0);
                                    break;
                            }
                            break;
                        case 4:
                            switch (Info.Endian)
                            {
                                case WVFEndianType.Big:
                                    dVal = BitConverter.ToInt32(bVal.Reverse().ToArray(), 0);
                                    break;
                                default:
                                    dVal = BitConverter.ToInt32(bVal, 0);
                                    break;
                            }
                            break;
                        case 8:
                            switch (Info.Endian)
                            {
                                case WVFEndianType.Big:
                                    dVal = BitConverter.ToInt64(bVal.Reverse().ToArray(), 0);
                                    break;
                                default:
                                    dVal = BitConverter.ToInt64(bVal, 0);
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                    break;
                case WVFByteFormatType.IU:
                    switch (byteNum)
                    {
                        case 2:
                            switch (Info.Endian)
                            {
                                case WVFEndianType.Big:
                                    dVal = BitConverter.ToUInt16(bVal.Reverse().ToArray(), 0);
                                    break;
                                default:
                                    dVal = BitConverter.ToUInt16(bVal, 0);
                                    break;
                            }
                            break;
                        case 4:
                            switch (Info.Endian)
                            {
                                case WVFEndianType.Big:
                                    dVal = BitConverter.ToUInt32(bVal.Reverse().ToArray(), 0);
                                    break;
                                default:
                                    dVal = BitConverter.ToUInt32(bVal, 0);
                                    break;
                            }
                            break;
                        case 8:
                            switch (Info.Endian)
                            {
                                case WVFEndianType.Big:
                                    dVal = BitConverter.ToUInt64(bVal.Reverse().ToArray(), 0);
                                    break;
                                default:
                                    dVal = BitConverter.ToUInt64(bVal, 0);
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                    break;
                case WVFByteFormatType.FS:
                    switch (byteNum)
                    {
                        case 4:
                            switch (Info.Endian)
                            {
                                case WVFEndianType.Big:
                                    dVal = BitConverter.ToSingle(bVal.Reverse().ToArray(), 0);
                                    break;
                                default:
                                    dVal = BitConverter.ToSingle(bVal, 0);
                                    break;
                            }
                            break;
                        case 8:
                            switch (Info.Endian)
                            {
                                case WVFEndianType.Big:
                                    dVal = BitConverter.ToDouble(bVal.Reverse().ToArray(), 0);
                                    break;
                                default:
                                    dVal = BitConverter.ToDouble(bVal, 0);
                                    break;
                            }
                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
    
            }
    
            listY.Add(Info.Groups[groupIndex].VOffset[traceIndex] + Info.Groups[groupIndex].VResolution[traceIndex] * dVal);
            listT.Add(Info.Groups[groupIndex].HOffset[traceIndex] + Info.Groups[groupIndex].HResolution[traceIndex] * (1 + i));
        }
    
        Info.Groups[groupIndex].TValues.Add(listT);
        Info.Groups[groupIndex].YValues.Add(listY);
    
    }

    5. 读取wvf的类

    View Code
    public class WVFFile
    {
        WVFInfo info = new WVFInfo();
        FileStream fs;
        BinaryReader reader;
        
        public WVFInfo Info
        {
            get { return info; }
            set { info = value; }
        }
    
        public WVFFile(string header, string file)
        {
           
            Info = new WVFInfo();
            ReadHDR(header);
            
            fs = new FileStream(file, FileMode.Open, FileAccess.Read);
            reader = new BinaryReader(fs);
    
    
            for(int i = 0; i < Info.GroupNumber; i++)
            {
                for (int j = 0; j < Info.Groups[i].TraceNumber; j++)
                {
                    ReadWVF(i, j);
                }
            }
    
            reader.Close();
            fs.Close();
        }
    
    }
  • 相关阅读:
    sql 自定义函数-16进制转10进制
    编写一个单独的Web Service for Delphi
    Web Service
    无需WEB服务器的WEBServices
    Svn总是提示输入账号密码
    阿里云服务器SQLSERVER 2019 远程服务器环境搭建
    svn客户端使用
    数据库设计规则(重新整理)
    数据库表字段命名规范
    怎样去掉DELPHI 10.3.3 启动后的 security alert 提示窗体
  • 原文地址:https://www.cnblogs.com/xpvincent/p/2844094.html
Copyright © 2011-2022 走看看