如何用python解码LTspice中的压缩二进制.RAW文件

2024-10-16 20:47:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着从.raw LTSPice文件中读取。在LTSPice的控制面板中,可以在ASCII和二进制压缩之间切换。ASCII是可读的,没有问题,但是它在大小和性能上有缺点,这就是为什么我要使用二进制压缩的原因。有可能选择二阶压缩,这就是目标。 LTSpice提供的是output.raw文件,ASCII文件有电压和电流的值,但在二进制文件中,有些符号我无法解码。在

首先我试图用记事本打开.raw文件。当我打开ASCII.raw文件时,Notpad++显示在左下角的UTF-8中,当打开二进制解压缩的.raw文件时,它显示在UCS-2 Little-Endian中。 我尝试过使用不同的编码方式,如UTF-16le、ISO-8859-1…实际上,我打印所有的编解码器并尝试使用它们:

import codecs
print(dir(codecs))

还有,我试过没有BOM。我找到了这个,但没有结果:

^{pr2}$

我发现Zlib是常见的压缩,我试图找出我的文件中的哪个位置有压缩,但没有得到结果。 我用过:

import zlib
from glob import glob

def zipstreams(filename):
    """Return all zip streams and their positions in file."""
    with open(filename, 'rb') as fh:
        data = fh.read()
    i = 0
    while i < len(data):
        try:
            zo = zlib.decompressobj()
            yield i, zo.decompress(data[i:])
            i += len(data[i:]) - len(zo.unused_data)
        except zlib.error:
            i += 1

for i, data in zipstreams("Circuit_binary_Transient.raw.raw"):
    print (i, len(data))

我总是为len(数据)取0。在

我找到了这个脚本,但是没有实现二进制.raw文件解码: http://www2.ee.unsw.edu.au/~tlehmann/ltspy.py
另外,我找到了Matlab的解决方案,Paul Wagner的LTSpice2Matlab(ltspice reader for Matlab),但python需要它,从那个特定的脚本中我找不到使用哪种编码。我发现对于二进制解压文件,paulwagner使用插值来获得更多的点,然后转换成可读的格式。在

实际上,我用这段代码来读取.raw文件:

data = fo.read() # Binary data read
fo.close()
line = str(data, encoding='utf-16le')
print(line)

当我使用ASCII.raw文件和UTF8时,在末尾有文本,但是当我使用二进制压缩的.raw文件时,我找不到如何以可读格式解码文件。在

这是我当前在LTSpice的.raw文件中的内容(在文本“Binary:”之后):

栋㲚朎㲚鸞㕼鸞㕼鸞땼䕘퇠≄뻕襾㷨⁄㷨⡜㚾⡜㚾⡜뚾䕘퇠≄㻥䏨㹔ᙘ㹓㜬㜬뜬岓逇Ⳡ㻵◲㻇㯋㻃㞟㞟랟ጟ箽㼄籼㼯덌㼩Ӏ㠋Ӏ㠋Ӏ렋괄蝄㼎ڕ㽦럍㽢먵㠹먵㠹먵령귴脍侧㼑з㽴鍰㽲럜㡆럜㡆럜롆쵺튆㼒㽺땺㽹迀㡌迀㡌迀롌偵姏䰦㼔㽾枎㽽雈㡏雈㡏雈롏䰼ᬇⅤ㼖쵅㽿ᦊ㽾⢖㡐⢖㡐⢖롐暾좳죯㼗챭㽼錒㽺䕈㡍䕈㡍䕈롍얳✀礦㼚嘻㽰㽫㿃㡁㿃㡁㿃롁먬쬥㼞㽉뙵㽁낁㠞낁㠞낁렞袨�봜㼢睿㻔瘵㻄㞠㞠랠嘈䆬흞㼦㷧븥譻븠蒱뜃蒱뜃蒱㜃빝袏噥㼪뼝뼙㼆럼㼆럼㼆㟼玵嬆㼬ﵠ뽐】뽏멬렩멬렩멬㠩떋Ҕ덭㼭葔뽩뽨챢렾챢렾챢㠾넼ꧼ㼮쏐뽵뼃뽵傴롉傴롉傴㡉뮷惵㼯툡뽻뽻婇롎婇롎婇㡎�ﶻሣ㼰姢뽿ᚶ뽿롐롐㡐誔

我希望解码并阅读此文件,我想我应该得到与ASCII.raw文件相同的结果,例如:

0       0.000000000000000e+000  
    1.884843971540818e-002  
    1.884796850054908e-002  
    9.423984250366810e-007  
    9.423984250274539e-007  
    -9.423984250328532e-007  
1       3.951925877448456e-008  
    1.959322256186405e-002  
    1.959271263253092e-002  
    9.796356316741367e-007  
    9.796356316265457e-007  
    -9.796356317259836e-007  
2       1.185577763234539e-007  
    2.108275522427772e-002  
    2.108216492289399e-002  
    1.054108246213077e-006  
    1.054108246144700e-006  
    -1.054108246245633e-006

我会很感激你的帮助。目标是读取压缩的二进制.raw LTSpice文件。在


Tags: 文件import目标readdatarawlenascii
2条回答

LTSpice的.RAW二进制文件的头可以用UTF-16解码。如果试图转换整个二进制原始文件,那么只有头将被转换为文本。最后一个用UTF-16成功转换为文本的字符是“Binary:”。在这之后,你应该得到“中国符号”或其他不可读的东西。在

我使用了一个十六进制编辑器,比较了同一电路的原始ASCII文件和原始二进制文件。在ASCII文件中,可以找到“Values:”而不是“Binary:”,然后是十进制值。因此,在hex编辑器的帮助下,可以比较二进制代码和原始ASCII文件中的实际值。在

经过比较,我成功地解码了一个原始二进制文件。下面写的都是十六进制的。我有6个变量。这对以下领域有效:直流扫描、直流操作、瞬态和直流传输(对于交流分析和噪声总是2 x 8字节的双精度解码)。在

  1. 在“Binary:”之后,总是有3个字节:000a00(0A-换行)
  2. 然后有8个字节,如果将其转换为双精度(float64),则给出正确的值
  3. 然后我有4个字节,如果把它转换成单精度(float32),它就给出了正确的值
  4. 给出一个值的4个字节重复5次(我有6个变量-标题“No.variables:”)
  5. 第2、3点。和4。重复进行,直到满足标题中“No.Points:”的数字。在

我用的是LTSpice XVII。 另外,我使用了HxD Hex编辑器https://mh-nexus.de/en/hxd/

编辑:非常重要:字节顺序是小尾数!
这意味着对于十六进制-aa77b8a2中的字节顺序,它应该以相反的顺序转换成-a2b877aa。 因此,AA 77 B8 A2十进制转换的单精度(float32)为-2.2e-13,A2 B8 77AA的十进制转换精度为-5e-18。在

Notpad++ shows in the bottom left UTF-8 when I open ASCII .raw files and UCS-2 Little Endian when open binary decompressed .raw files."

这很正常,UTF-8是一种文本编码,它只是将一个字节序列与某个字符相关联。原始二进制文件没有固定的结构或编码,因为它们包含二进制数据:例如,想想字符串"3.1415926535"(在UTF-8中是12个字节)和该值的原始浮点二进制表示(4个字节)之间的区别。如果将浮点的“原始”4字节解释为文本,则会得到一些垃圾文本输出或unicode解码错误。对于原始文件,特定的数据格式和每个字节的含义由生成它们的软件指定。在

通常,您应该查找LTSpice原始文件规范,了解数据是如何排列的,并为自己编写一个解析器。但是,由于这是python,someone already did that for you and made a package you can install via ^{},请查找该包及其示例,它应该很容易使用。在


更新

this link上,他们声明原始二进制格式没有正式公开,并且随时可能改变(尽管在过去的15年里没有)。在

格式本身是一个UTF-16头,后面跟着原始二进制数据。 当你说:

This is what I have currently in .raw file from LTSpice (After text "Binary:"): [...]

这是原始数据(在UTF-16解码,正如您所见,这在文本中是无稽之谈)。原始数据是变量值的压缩列表,按头文件中定义的顺序排列,重复数据中的时间点。时间是用双精度编码的(即8字节),其他任何东西——除非你强迫它也加倍——都是在float中(4字节)。 那么,你应该做的是:

1)解析变量列表并计算一条记录的长度(例如,8+4*num_of_variables)

2)从“二进制”字符串中获取字节数据,直到文件结束, 然后按照第一步的长度把它分成块

3)相应地解释记录中的字节

相关问题 更多 >