我遇到了从文件(* .ADB)读取二进制数据的问题,该文件是地震台站的输出。 这里的主要思想是从* .ADB中读取数据并将其保存为解压缩的结构化ASCII文件,该文件将由DSP链中的下一个脚本读取,或者通过任何表处理器或CAD软件查看。
我已经从它的创建者那里请求了一个文件结构,它如下:
首先是一个包含不同技术和元信息的标题:
PARAMETER NAME | OFFSET (WORDS) | PARAMETER SIZE
station name 0 36
station # 18 2
profile # 19 2
observation point # 20 2
shotpoint # 21 2
...etc
sample format 35 2
...etc
然后说如果样本格式为'0',那么数据结构如下:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
15 – sign, 0=1 (positive number), 1=-1 (negative number)
14-13 – channel number
12-10 – order
9-0 – fixed point part
样本存储在一个特殊的结构中:
CHANNEL NUMBER | PARAMETER | PARAMETER SIZE (WORDS)
1 maxAmp/Chn1 4
first sample 2
...etc
last sample 2
N ...etc
我知道活动地震台站通道的数量是3(对于地震信号的Z,X和Y分量),但我不知道实际的样本格式,因为我还没有读过标题。 / p>
所以要做的第一件事是读取标题,我应该使用什么,'struct'或'bitstring'?我正在运行'little-endian'的windows机器。
好的,让我透露一下实际的代码(适用于我阅读标题):
# importing all the needed modules
import struct
# open binary file in a read mode
file = open('C:/01.adb', 'rb')
# creating array of header data block sizes
readsize = (36,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,2,2,2,2,2,10,2,4,4,4,4,4,2,2,2,2,2,2,2,2,2,126)
print('Readsize array length: '+str(len(readsize)))
# guessing the header structure with python data types, creating structure
formatstring = '<36s H H H H H H H H H H H H H H H I H H H H H 10s H f f f 4s f H H H H H H H H H 126s'
adbstruct = struct.Struct(formatstring)
# calculating guessed little-endian fmt (formatstring) size
print('Calculated structure size: '+str(struct.calcsize(formatstring)))
# calculating header block size based on 'readsize' array (usually 256 bytes for *.ADB)
packed_size = 0
for i in range(len(readsize)): packed_size = packed_size+readsize[i]
print('Calculated header size: '+str(packed_size)+'\n')
# reading packed data of 'packed_size' length
packed_data = file.read(packed_size)
file.close()
# printing header represented in data types defined by formatstring
print(struct.unpack(formatstring,packed_data))
上面的代码完成了它的工作(我想,因为我得到了一些参数,我得到了预期值),这是脚本输出:
Readsize array length: 39
Calculated structure size: 256
Calculated header size: 256
(b'LogiS (C)2000, DELTA Software, V2.6 ', 143, 1, 1, 1, 12, 5, 29, 8, 0, 2, 800, 35, 1, 1, 3, 513024, 2, 1, 1, 33604, 65519, b'\x12U\x0e\x00\x86\x0b\x12\x00\xd7\xed', 1, 1.0, 0.0, 0.0, b'\x00\x00\x00\x00', 0.0, 0, 0, 0, 0, 0, 0, 0, 0, 0, b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
接下来我正在做的是读取数据块,我想我将整体样本数除以通道数513024/3 = 171008。这意味着我必须为每个通道读取171008块大小为2的块和1块大小为4的块。
样本格式字节表示它是'2',这不是我所期望的,但它没关系。在读取2字节样本后,如何执行逐位处理?
据说样本格式'2'代表32位字,带有用于存储负数的互补代码,我想在python中可能有一些很好的方法来读取theese的包?