#!/usr/bin/env python3 ''' Version 0.85 By S.N. DONE: + missing data (gap): code ha dasai + variable sampling rate (gap) + time zone TODO: + misisng data (zero-pad, hold-prev-data) + WIN32 ''' import sys import ctypes as C import numpy as np import struct from obspy import Stream, Trace, UTCDateTime import time TZ = '+0900' #TZ = '' HEADER_5B = 1048576 MAX_SR = HEADER_5B __clibwinsystem = C.CDLL("/usr/local/win/lib/libwinsystem.so") __clibwinsystem.bcd_dec.argtypes = (C.c_int * 6, C.c_char_p) __clibwinsystem.bcd_dec.restype = None __clibwinsystem.win2fix.argtypes = (C.c_char_p, np.ctypeslib.ndpointer(dtype=np.int32, ndim=1, flags='C_CONTIGUOUS'), C.POINTER(C.c_uint), C.POINTER(C.c_long)) __clibwinsystem.win2fix.restype = C.c_ulong __clibwinsystem.win_chheader_info.argtypes = (C.c_char_p, C.POINTER(C.c_uint), C.POINTER(C.c_long), C.POINTER(C.c_int)) __clibwinsystem.win_chheader_info.restype = C.c_ulong class windata: def __init__(self, chid, begintime, endtime, sr, d): self.chid = chid self.begintime = begintime self.endtime = endtime self.sr = sr self.d = d def _read_onesec(data, start, output, ch2tr, maxtr): tt = (C.c_int * 6)(0,0,0,0,0,0) abuf = np.empty(MAX_SR, dtype=np.int32) g_size = C.c_ulong() sys_ch = C.c_uint() s_rate = C.c_long() blksizetmp = data[start:start+4] blksize = struct.unpack(">I", blksizetmp)[0] buff = data[start+4:start+10] __clibwinsystem.bcd_dec(tt, buff) if tt[0] < 70: tt[0] += 2000 else: tt[0] += 1900 begdate = UTCDateTime(tt[0], tt[1], tt[2], tt[3], tt[4], tt[5]) prevdate = begdate - 1 blksize -= 10 buff = data[start+10:start+10+blksize] offset = 0 while offset < blksize: g_size = __clibwinsystem.win2fix(buff[offset:], abuf, sys_ch, s_rate) chid = sys_ch.value if chid in ch2tr and output[ch2tr[chid]].endtime == prevdate and output[ch2tr[chid]].sr == s_rate.value: ii = ch2tr[chid] output[ii].d = np.append(output[ii].d, abuf[0:s_rate.value]) output[ii].endtime = begdate.timestamp else: ii = maxtr maxtr = maxtr + 1 ch2tr[chid] = ii output.append(windata(chid, begdate.timestamp, begdate.timestamp, s_rate.value, np.copy(abuf[0:s_rate.value]))) offset += g_size del(abuf) return((blksize + 10, maxtr)) def read_winfile(fname): output = [] ch2tr = {} maxtr = 0 with open(fname, "rb") as fpin: data = fpin.read() datasize = len(data) offset = 0 while offset < datasize: (blksize, maxtr) = _read_onesec(data, offset, output, ch2tr, maxtr) offset += blksize fpin.close() traces = [] for i in range(maxtr): t = Trace(data=np.array(output[i].d).flatten()) t.stats.channel = format(output[i].chid, '04X') t.stats.sampling_rate = float(output[i].sr) if not TZ: t.stats.starttime = UTCDateTime(output[i].begintime) else: stime0 = str(UTCDateTime(output[i].begintime)) stime1 = stime0.replace('Z', TZ) t.stats.starttime = UTCDateTime(stime1) # print('DEBUG %s %s %s' % (stime0, stime1, t.stats.starttime)) traces.append(t) del(output) del(ch2tr) return Stream(traces=traces) if __name__ == '__main__': winfname="991109.064607" time_sta = time.perf_counter() st = read_winfile(winfname) time_end = time.perf_counter() ela_time = time_end - time_sta print('Ellapsed time = %f sec' % ela_time) chid = "020*" st2 = st.select(channel=chid) print(st2) st2.plot() sys.exit(0)