ここで、地震観測所の出力であるファイル (*.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 成分) であることはわかっていますが、ヘッダーをまだ読んでいないため、実際のサンプル形式についてはわかりません。
最初に行うことは、そのヘッダーを読み取ることです。'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 で割っていると思います。つまり、チャネルごとにサイズ 2 の 171008 ブロックとサイズ 4 の 1 つの先行ブロックを読み取る必要があります。
サンプル フォーマット バイトは '2' だと言っていますが、これは私が期待したものではありませんが、問題ありません。2 バイトのサンプルを読み取った後、ビットごとの処理を実行するにはどうすればよいですか?
サンプル形式「2」は、負の数を格納するための補完的なコードを含む 32 ビットの単語を表すと言われています。Python でこれらのパックを読み取る良い方法があると思いますか?