1

我被困在从一个文件(* .ADB)读取二进制数据的问题上,该文件是地震台的输出。这里的主要想法是从 *.ADB 读取数据并将其保存为解压缩的结构化 ASCII 文件,该文件将由 DSP 链中的下一个脚本读取,或使用任何表格处理器或 CAD 软件进行查看。

我已经向它的创建者请求了一个文件结构,它如下所示:

  1. 首先有一个包含不同技术和元信息的标题:

    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
    
  2. 那么据说如果样本格式为“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
    
  3. 样本存储在一个特殊的结构中:

    CHANNEL NUMBER | PARAMETER | PARAMETER SIZE (WORDS)
           1        maxAmp/Chn1        4
                    first sample       2
                    ...etc
                    last sample        2
           N        ...etc
    

我知道活动地震台站通道的数量是 3(对于地震信号的 Z、X 和 Y 分量),但我不知道实际的样本格式,因为我还没有阅读标题。

所以要做的第一件事就是阅读那个标题,我应该使用什么,'struct'还是'bitstring'?我正在运行“小端”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中读取这些包?

4

0 回答 0