Electronic Engineer Discuss

View: 2446|Reply: 0
Print Prev. thread Next thread

汉泰.doc=>力科.trc转换程序

[Copy link]

1

Threads

8

Posts

8

Credits

新手上路

Rank: 1

Credits
8
Jump to specified page
1#
Post time 2023-6-30 13:43:32 | Show the author posts only Reply Awards |Descending |Read mode
第一级代码(by Python):
  1. # code by fengxh.
  2. # transfer 汉泰.doc => Lecroy 二进制.trc格式。
  3. # python code is created at Jun30,2023

  4. from scipy.optimize import curve_fit
  5. import numpy as np
  6. import csv
  7. import sys
  8. import operator
  9. import subprocess
  10. import re


  11. # 取csv文件的第N列,抛弃掉标题栏,返回数组
  12. def load_csv_data(filename, idxBase0):
  13.     data = []  # 存放结果的数组

  14. # 打开CSV文件,并读取数据
  15.     flagDataStart = False;
  16.     with open(filename, 'r') as f:
  17.         reader = csv.reader(f)
  18.         i = 0;
  19.         for row in reader:
  20.             i = i+1;
  21.             #print(i);
  22.             if len(row) == 0:
  23.                 if(not flagDataStart):
  24.                     flagDataStart = True;
  25.                     continue;
  26.                 else:
  27.                     break; #done!
  28.             if(not flagDataStart): continue;
  29.             try:
  30.                data.append(float(row[idxBase0]))  # 取第一列数据,并转为float类型
  31.             except:
  32.                 continue;
  33.     return data;

  34. # 取csv文件的第N列,抛弃掉标题栏,返回数组
  35. def get_time_scale(filename):
  36.     flagDataStart = False;
  37.     #string = "#CLOCK=0.004000000S"
  38.     pattern = r"CLOCK=(\d+\.\d+)S"
  39.     with open(filename, 'r') as f:
  40.         reader = csv.reader(f)
  41.         for row in reader:
  42.             match = re.search(pattern, str(row))
  43.             if match:
  44.                 result = float(match.group(1));
  45.                 return result;
  46.     return 100e-6;


  47. def getRmsOfFreq(arFreq, arRms, freq):
  48.     for i in range(0, len(arFreq)):
  49.         if(arFreq[i] == freq): return arRms[i];

  50. def csv2trc(csvfile, trcfile, ratio):
  51. # 要执行的命令
  52. #Usage: Csv2Trc <src.csv> <tgt.trc> [<sample_rate=100e-6> <volPerAd>=1]   
  53.     command = r"C:\Users\fengxh\Desktop\工具集\dumb\Csv2Trc_V1.0.20230531\SampleData_CSV2LecoryTrc";
  54.     command = command + " " +csvfile + ' ' + trcfile + ' ' + str(ratio);
  55.     # 执行命令并获取输出
  56.     output = subprocess.check_output(command, shell=True)
  57.     output = output.decode()  # 如果你想要将输出作为字符串处理,可以解码为返回的字节字符串
  58.     print(output)

  59. def toInteger(rms):
  60.     vals = [];
  61.     for i in rms:
  62.         if(not i in vals):
  63.             vals.append(i);

  64.     sorted_vals = sorted(vals);

  65.     my_dict = {sorted_vals[0]:1};
  66.     idx = 1;
  67.     for v in sorted_vals:
  68.         my_dict[v] = idx;
  69.         idx = idx +1;

  70.     ret = [];
  71.     for i in rms:
  72.         ret.append(my_dict[i]);
  73.             
  74.     return ret;


  75. def zoom_out_lecory_wave_data(filename, ratio=10):
  76.     rms = load_csv_data(filename, 0);  #rms
  77.     dt = get_time_scale(filename);
  78.     print("数据的时间跨度", dt, "秒, 数据点数:", len(rms));
  79.     rms = toInteger(rms);
  80.     data = rms[:];
  81.     for i in range(0, len(rms)):
  82.         data[i//round(ratio) + round(i%(round(ratio))*len(rms)/ratio)] = rms[i];

  83.     data_2d = [[element] for element in data]
  84.     filename = filename + '.zoom_out' + str(ratio) + ".csv";
  85.     with open(filename, 'w', newline='') as csvfile:
  86.         writer = csv.writer(csvfile)
  87.         writer.writerows(data_2d)
  88.     csv2trc(filename, filename+".trc", dt*ratio/len(rms));
  89.     print("done!");

  90. #调用示例
  91. filename = "35.25_40K.doc";
  92. zoom_out_lecory_wave_data(filename,1);
Copy the Code
第二级代码,SampleData_CSV2LecoryTrc,writened in C#, build by VS2022
  1. /*
  2. *  lecroy_trc.cs
  3. *  
  4. *  A csv to lecory .trc bin file format helper modules.
  5. *  
  6. *  thanks to Lecroy, for its powerful offline wavefrom analyse tools.
  7. *  and Surrea1@CSDN for provide the .trc file format.
  8. *  
  9. *  ----
  10. *  V1.0.20230530 by twicave
  11. *          created. the first verison, coding in vs2022(c#)
  12. *  
  13. */

  14. using System;
  15. using System.Collections.Generic;
  16. using System.Data.SqlTypes;
  17. using System.Diagnostics.SymbolStore;
  18. using System.Linq;
  19. using System.Reflection.PortableExecutable;
  20. using System.Security.Cryptography;
  21. using System.Text;
  22. using System.Threading;
  23. using System.Threading.Tasks;
  24. using System.Runtime.InteropServices;
  25. using static System.Net.Mime.MediaTypeNames;
  26. using System.ComponentModel;

  27. namespace SampleData_CSV2LecoryTrc
  28. {

  29.     internal class lecroy_trc
  30.     {
  31.         static byte[] lecroy_trc_header = new byte[]{
  32.         0x23,0x39,0x30,0x30,0x32,0x30,0x30,0x30,0x31,0x34,0x34,0x57,0x41,0x56,0x45,0x44,
  33.         0x45,0x53,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4C,0x45,0x43,0x52,0x4F,
  34.         0x59,0x5F,0x32,0x5F,0x33,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x5A,
  35.         0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  36.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB6,0x83,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,
  37.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4C,0x45,0x43,0x52,0x4F,0x59,0x57,0x53,0x34,
  38.         0x32,0x34,0x00,0x00,0x00,0x00,0x00,0x4B,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  39.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x41,0x0F,0x00,0xDB,
  40.         0x41,0x0F,0x00,0x40,0x42,0x0F,0x00,0x00,0x00,0x00,0x00,0xDA,0x41,0x0F,0x00,0x00,
  41.         0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,
  42.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0D,0x00,0x80,0x39,0x00,0x00,0x00,0xBF,0x00,
  43.         0x00,0xFE,0x46,0x00,0x00,0x00,0xC7,0x0B,0x00,0x01,0x00,0xBD,0x37,0x06,0x35,0x1E,
  44.         0xF4,0xC8,0xB6,0x68,0x78,0xD1,0xBF,0x46,0xB6,0xF3,0xFD,0xD4,0x78,0xD1,0xBF,0x56,
  45.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  46.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  47.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x53,
  48.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  49.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  50.         0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,
  51.         0xEB,0xAF,0x2C,0x99,0xBC,0x0B,0xD8,0x31,0x27,0x39,0x40,0x02,0x0F,0x1A,0x04,0xE7,
  52.         0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x20,
  53.         0x00,0x02,0x00,0x00,0x00,0x80,0x3F,0x13,0x00,0x00,0x00,0x00,0x00,0x80,0x3F,0x00,
  54.         0x00,0x00,0xBF,0x00,0x00 };

  55.         public class trc_field_define
  56.         {
  57.             public string standardName;
  58.             public string field_name;
  59.             public int offetIdxbase0;
  60.             public int len;
  61.             public string type;
  62.             public string memo;
  63.             public string example;
  64.             public trc_field_define(string standardName, string field_name, int offsetIdxbase0, int len, string type, string memo, string example)
  65.             {
  66.                 this.standardName = standardName;
  67.                 this.field_name = field_name;
  68.                 this.offetIdxbase0 = offsetIdxbase0;
  69.                 this.len = len;
  70.                 this.type = type;
  71.                 this.memo = memo;
  72.                 this.example = example;
  73.             }
  74.         };

  75.         static List<trc_field_define> trc_header_fields = new List<trc_field_define>{
  76.             new trc_field_define("totalLength","文件总长字段", 0, 11, "string", "%文件头,主要用于指示文件大小,数值为9e10+文件字节长度(不包括此文件头的11个字节)", "#9020000350"),
  77.             new trc_field_define("no_use","大小端", 11+34, 2, "u16", "数据大小端", "=1小端"),
  78.             new trc_field_define("no_use", "文件头长", 11+36, 4, "u32", "%文件头WAVEDSEC块的长度,4B, long, 36-39", "可认为定长:346,+11字节头部=0x165 == sizeof(lecroy_trc_header)"),
  79.             new trc_field_define("allDataLength","波形数据总长", 11+60, 4, "u32", "WAVE_ARRAY_1,%4B,long,60-63,数据列1长度", "20000004,一般是采样点数总长=时间+数据"),
  80.             new trc_field_define("timeDataLength","时间数据总长", 11+112, 4, "u32", "", "10000002, 为波形数据总长/2"),
  81.             new trc_field_define("sampleDataLength","采样数据总长", 11+116, 4, "u32", "", "10000002,为波形数据总长/2"),
  82.             new trc_field_define("pntsPerScreen","PNTS_PER_SCREEN", 11+120, 4, "u32", "区间数", "为波形数据总长/2-2"),
  83.             new trc_field_define("lastvalidPnts","LAST_VALID_PNT", 11+128, 4, "u32", "区间最后一个数据点", "为波形数据总长/2-1"),
  84.             new trc_field_define("vertical_gain","VERTICAL_GAIN", 11+156, 4, "float", "最终的数值=采样值*Gain+offset", "1.373120030621067e-04"),
  85.             new trc_field_define("vertical_offset","VERTICAL_OFFSET", 11+160, 4, "float", "垂直零点", "0"),
  86.             new trc_field_define("max","MAX_VALUE", 11+164, 4, "u32", "最大值", "28875"),
  87.             new trc_field_define("min","MIN_VALUE", 11+168, 4, "u32", "最小值", "-29131"),
  88.             new trc_field_define("horizInterval","HORIZ_INTERVAL", 11+176, 4, "float", "采样率", "1e-10"),
  89.             new trc_field_define("horizOffset","HORIZ_OFFSET", 11+180, 8, "double", "水平偏移", "-5e-4"),
  90.             new trc_field_define("pixelOffset","PIXEL_OFFSET", 11+188, 8, "u32", "屏幕当前偏移?", "-5e-4"),
  91.             new trc_field_define("horiz_uncertainty","HORIZ_UNCERTAINTY", 11+292, 4, "float", "区间数", "1e-12,采样率的1%"),
  92.             new trc_field_define("timeBase","TIMEBASE", 11+324, 2, "u16", "水平栅格时长?这是enum", "24"),
  93.             new trc_field_define("fixed_Vert_Gain","FIXED_VERT_GAIN", 11+332, 2, "u16", "垂直固定增益?enum", "18")
  94.         };

  95.         public struct trcHeaderFields
  96.         {
  97.             public string totalLength; //0x9e10+0x0b+lenOfAd*2 "#...."
  98.             public int allDataLength; //2*lenOfAd(bytes)
  99.             public int timeDataLength; //lenOfAd;
  100.             public int sampleDataLength; //lenOfAd;
  101.             public int pntsPerScreen; //lenfOfAd-2;
  102.             public int lastvalidPnts; //lenOfAd-1
  103.             public float vertical_gain; //垂直增益
  104.             public UInt32 vertical_offset; //垂直偏移
  105.             public UInt32 max;
  106.             public UInt32 min;
  107.             public float horizInterval; //采样率
  108.             public double horizOffset; //中心点
  109.             public double pixelOffset; //又一个水平偏移
  110.             public float horiz_uncertainty; //samplerate/4
  111.             public UInt16 timeBase; //水平档位
  112.             public UInt16 fixed_Vert_Gain; //垂直档位
  113.         };

  114.         public static Dictionary<string, trc_field_define> dicOfFields = new Dictionary<string, trc_field_define>() { };


  115.         static public bool WriteTrcFromCsv(float sampleRate, float volPerAd, uint[] sampleData, FileInfo fi)
  116.         {
  117.             bool ret  = false;

  118.             /*
  119.              * %Header
  120.                %用户文本块
  121.                     TEXT % 视上面定义的长度而定
  122.                % TRIGTIME
  123.                     TRIGGER_T % 8B f 原名结尾是TIME,但与前面定义重复,故改为T
  124.                     TRIGGER_OFFSET % 8B f
  125.                % RISTIME
  126.                     RIS_OFFSET % 8B f
  127.                % DATA_ARRAY_1
  128.                     DATA_ARRAY_1
  129.                % DATA_ARRAT_2
  130.                     DATA_ARRAY_2
  131.                % SIMPLE
  132.                     SIMPLE int16模式
  133.                % DUAL
  134.                     版权声明:本文为CSDN博主「Surrea1」的原创文章,遵循CC 4.0 BY - SA版权协议,转载请附上原文出处链接及本声明。
  135.                     原文链接:https://blog.csdn.net/Surrea1/article/details/126807087
  136.             */
  137.             try
  138.             {
  139.                 int totallength = lecroy_trc_header.Length + 2 * sampleData.Length - 11; //no 11 more
  140.                 StringBuilder sb = new StringBuilder();
  141.                 sb.AppendFormat("#9{0:000000000}", totallength);

  142.                 trcHeaderFields headerFields;
  143.                 headerFields.totalLength = sb.ToString();
  144.                 headerFields.timeDataLength = sampleData.Length;
  145.                 headerFields.sampleDataLength = sampleData.Length;
  146.                 headerFields.allDataLength = sampleData.Length * 2; //in bytes.
  147.                 headerFields.horizInterval = sampleRate;
  148.                 headerFields.horizOffset = 0;
  149.                 headerFields.horiz_uncertainty = sampleRate / 4;
  150.                 headerFields.pixelOffset = 0;
  151.                 headerFields.pntsPerScreen = sampleData.Length;
  152.                 headerFields.lastvalidPnts = sampleData.Length-1;
  153.                 headerFields.vertical_gain = volPerAd; //垂直增益
  154.                 headerFields.vertical_offset = 0; //垂直偏移
  155.                 headerFields.timeBase = 15;
  156.                 headerFields.fixed_Vert_Gain = 1; //垂直增益

  157.                 byte[] header = new byte[lecroy_trc_header.Length];
  158.                 for (int i = 0; i < header.Length; ++i)
  159.                 {
  160.                     header[i] = 0;
  161.                 }
  162.                 lecroy_trc_header.CopyTo(header, 0);


  163.                 if (dicOfFields.Count == 0)
  164.                 {
  165.                     foreach (trc_field_define i in trc_header_fields)
  166.                     {
  167.                         if (dicOfFields.ContainsKey(i.standardName)) continue;
  168.                         dicOfFields.Add(i.standardName, i);
  169.                     }
  170.                 }
  171.                 Encoding.ASCII.GetBytes(headerFields.totalLength).CopyTo(header, dicOfFields["totalLength"].offetIdxbase0);
  172.                 BitConverter.GetBytes(headerFields.timeDataLength).CopyTo(header, dicOfFields["timeDataLength"].offetIdxbase0);
  173.                 BitConverter.GetBytes(headerFields.sampleDataLength).CopyTo(header, dicOfFields["sampleDataLength"].offetIdxbase0);
  174.                 BitConverter.GetBytes(headerFields.allDataLength).CopyTo(header, dicOfFields["allDataLength"].offetIdxbase0);
  175.                 BitConverter.GetBytes(headerFields.horizInterval).CopyTo(header, dicOfFields["horizInterval"].offetIdxbase0);
  176.                 BitConverter.GetBytes(headerFields.horizOffset).CopyTo(header, dicOfFields["horizOffset"].offetIdxbase0);
  177.                 BitConverter.GetBytes(headerFields.horiz_uncertainty).CopyTo(header, dicOfFields["horiz_uncertainty"].offetIdxbase0);
  178.                 BitConverter.GetBytes(headerFields.pixelOffset).CopyTo(header, dicOfFields["pixelOffset"].offetIdxbase0);
  179.                 BitConverter.GetBytes(headerFields.pntsPerScreen).CopyTo(header, dicOfFields["pntsPerScreen"].offetIdxbase0);
  180.                 BitConverter.GetBytes(headerFields.lastvalidPnts).CopyTo(header, dicOfFields["lastvalidPnts"].offetIdxbase0);
  181.                 BitConverter.GetBytes(headerFields.vertical_gain).CopyTo(header, dicOfFields["vertical_gain"].offetIdxbase0);
  182.                 BitConverter.GetBytes(headerFields.vertical_offset).CopyTo(header, dicOfFields["vertical_offset"].offetIdxbase0);
  183.                 BitConverter.GetBytes(headerFields.timeBase).CopyTo(header, dicOfFields["timeBase"].offetIdxbase0);
  184.                 BitConverter.GetBytes(headerFields.fixed_Vert_Gain).CopyTo(header, dicOfFields["fixed_Vert_Gain"].offetIdxbase0);

  185.                 FileStream fs = new FileStream(fi.FullName, FileMode.OpenOrCreate, FileAccess.Write);
  186.                 BinaryWriter bw = new BinaryWriter(fs);

  187.                 /*(byte[] zero24 = new byte[24];
  188.                 for (int i = 0; i < zero24.Length; ++i)
  189.                 {
  190.                     zero24[i] = 0;
  191.                 }
  192.                 bw.Write(zero24);*/
  193.                
  194.                 UInt16 min = UInt16.MaxValue;
  195.                 UInt16 max = UInt16.MinValue;
  196.                 foreach (uint data in sampleData)
  197.                 {
  198.                     UInt16 d16 = (UInt16)data;
  199.                     if(min>d16) min = d16;
  200.                     if(max<d16) max = d16;
  201.                 }
  202.                 BitConverter.GetBytes((float)min).CopyTo(header, dicOfFields["min"].offetIdxbase0);
  203.                 BitConverter.GetBytes((float)max).CopyTo(header, dicOfFields["max"].offetIdxbase0);
  204.                 bw.Write(header);
  205.                 foreach (uint data in sampleData)
  206.                 {
  207.                     UInt16 d16 = (UInt16)data;
  208.                     bw.Write(BitConverter.GetBytes(d16));
  209.                 }

  210.                 bw.Flush();
  211.                 fs.Close();
  212.                 ret = true;
  213.             }
  214.             catch (Exception ex)
  215.             {
  216.                 Console.WriteLine(ex.Message);
  217.                 return false;
  218.             }

  219.             return ret;

  220.         }
  221.     }
  222. }
Copy the Code

python代码中,波形抽样,扩容的代码是第一版的代码,后续改进的部分欠奉。
C#代码中.csv的读取代码欠奉。

最终在力科分析软件中运行的效果如下:

时基的部分做了调整,但是ad值部分,没有对照档位做适配。有兴趣的同志可以在这些代码的基础上继续工作。

This post contains more resources

You have to Login for download or view attachment(s). No Account? Register

x
Reply

Use magic Report

You have to log in before you can reply Login | Register

Points Rules

Dark room|Mobile|Archiver|Electronic Engineer Discuss

2024-4-27 20:54 GMT+8 , Processed in 0.176600 second(s), 21 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

Quick Reply To Top Return to the list