# -*- coding: utf-8 -*-
"""
DATAMARK bindings to ObsPy core module.
"""
from obspy import Trace, UTCDateTime, Stream
import numpy as np
import warnings
def isDATAMARK(filename): # @UnusedVariable
"""
Checks whether a file is DATAMARK or not.
:type filename: string
:param filename: DATAMARK file to be checked.
:rtype: bool
:return: ``True`` if a DATAMARK file.
"""
# as long we don't have full format description we just try to read the
# file like readDATAMARK and check for errors
try:
fpin = open(filename, "rb")
pklen = fpin.read(4)
_truelen = np.fromstring(pklen, '>i')[0] # equiv to Str4Int
buff = fpin.read(6)
yy = "%s%x" % (20, np.fromstring(buff[0], dtype='b')[0])
mm = "%x" % np.fromstring(buff[1], dtype='b')[0]
dd = "%x" % np.fromstring(buff[2], dtype='b')[0]
hh = "%x" % np.fromstring(buff[3], dtype='b')[0]
mi = "%x" % np.fromstring(buff[4], dtype='b')[0]
sec = "%x" % np.fromstring(buff[5], dtype='b')[0]
_date = UTCDateTime(int(yy), int(mm), int(dd), int(hh), int(mi),
int(sec))
buff = fpin.read(4)
_flag = np.fromstring(buff[0], dtype='b')[0]
_chanum = np.fromstring(buff[1], dtype='b')[0]
_datawide = np.fromstring(buff[2], dtype='b')[0] >> 4
_srate = np.fromstring(buff[3], dtype='b')[0]
idata00 = fpin.read(4)
_idata22 = np.fromstring(idata00, '>i')[0]
except:
return False
return True
def readDATAMARK(filename, century="20", **kwargs): # @UnusedVariable
"""
Reads a DATAMARK file and returns a Stream object.
.. warning::
This function should NOT be called directly, it registers via the
ObsPy :func:`~obspy.core.stream.read` function, call this instead.
:type filename: string
:param filename: DATAMARK file to be read.
:param century: DATAMARK stores year as 2 numbers, need century to
construct proper datetime.
:rtype: :class:`~obspy.core.stream.Stream`
:returns: Stream object containing header and data.
"""
output = {}
# read datamark file
with open(filename, "rb") as fpin:
fpin.seek(0, 2)
sz = fpin.tell()
fpin.seek(0)
leng = 0
status0 = 0
start = 0
while leng < sz:
pklen = fpin.read(4)
if len(pklen) == 0:
break # EOF
leng = 4
truelen = np.fromstring(pklen, '>i')[0] # equiv to Str4Int
buff = fpin.read(6)
leng += 6
yy = "%s%x" % (century, np.fromstring(buff[0], dtype='b')[0])
mm = "%x" % np.fromstring(buff[1], dtype='b')[0]
dd = "%x" % np.fromstring(buff[2], dtype='b')[0]
hh = "%x" % np.fromstring(buff[3], dtype='b')[0]
mi = "%x" % np.fromstring(buff[4], dtype='b')[0]
sec = "%x" % np.fromstring(buff[5], dtype='b')[0]
date = UTCDateTime(int(yy), int(mm), int(dd), int(hh), int(mi),
int(sec))
if start == 0:
start = date
if status0 == 0:
sdata = None
while leng < truelen:
buff = fpin.read(4)
leng += 4
_flag = np.fromstring(buff[0], dtype='b')[0]
chanum = np.fromstring(buff[1], dtype='b')[0]
datawide = np.fromstring(buff[2], dtype='b')[0] >> 4
srate = np.fromstring(buff[3], dtype='b')[0]
xlen = (srate - 1) * datawide
idata00 = fpin.read(4)
leng += 4
idata22 = np.fromstring(idata00, '>i')[0]
if chanum in output:
output[chanum].append(idata22)
else:
output[chanum] = [idata22, ]
sdata = fpin.read(xlen)
leng += xlen
if len(sdata) < xlen:
fpin.seek(-(xlen - len(sdata)), 1)
sdata += fpin.read(xlen - len(sdata))
msg = "This shouldn't happen, it's weird..."
warnings.warn(msg)
for i in range((xlen / datawide)):
idata2 = 0
if datawide == 1:
idata2 = np.fromstring(sdata[i:i + 1], 'b')[0]
elif datawide == 2:
idata2 = np.fromstring(sdata[2 * i:2 * (i + 1)],
'>h')[0]
elif datawide == 3:
idata2 = np.fromstring(sdata[3 * i:3 * (i + 1)] + ' ',
'>i')[0] >> 8
elif datawide == 4:
idata2 = np.fromstring(sdata[4 * i:4 * (i + 1)],
'>i')[0]
else:
msg = "DATAWIDE is %s " % datawide + \
"but only values of 1, 2, 3 or 4 are supported."
raise NotImplementedError(msg)
idata22 += idata2
output[chanum].append(idata22)
traces = []
for i in output.keys():
t = Trace(data=np.array(output[i]))
t.stats.channel = str(i)
t.stats.sampling_rate = float(srate)
t.stats.starttime = start
traces.append(t)
return Stream(traces=traces)
|