snr_bias / code /utils /msriterator.py
cangyeone's picture
Upload GRL reproducibility package
7170296 verified
Raw
History Blame Contribute Delete
5.84 kB
# -*- coding: utf-8 -*-
"""
Convenience class for iterating over miniSEED records in a file.
Version 2017.114
"""
from __future__ import (absolute_import, division, print_function,
unicode_literals)
from future.builtins import * # NOQA
import ctypes as C
import os
from obspy import UTCDateTime
from obspy.io.mseed.headers import (HPTMODULUS, MS_NOERROR, MS_ENDOFFILE,
MSFileParam, MSRecord, clibmseed)
class MSR_iterator(object):
"""
Class for iterating through miniSEED records in a file.
:ivar msr: MSRecord (pointer to)
:ivar msf: MSFileparam (pointer to)
:ivar file: filename
:ivar offset: Current offset
:param filename: File to read
:param startoffset: Offset in bytes to start reading the file
:param reclen: If reclen is 0 the length of the first record is auto-
detected. All subsequent records are then expected to have the
same record length. If reclen is negative the length of every
record is automatically detected. Defaults to -1.
:param dataflag: Controls whether data samples are unpacked, defaults
to False.
:param skipnotdata: If true (not zero) any data chunks read that to do
not have valid data record indicators will be skipped. Defaults to
True (1).
:param verbose: Controls verbosity from 0 to 2. Defaults to None (0).
.. rubric:: Notes
The elements of the MSRecord struct are available through `contents`
on the pointer to the MSrecord, e.g. `MSR_iterator.msr.contents.reclen`.
The raw record as a byte array is available at:
`MSR_iterator.msr.contents.record`
and can be used with Python I/O routines using:
`ctypes.string_at(MSR_iterator.msr.contents.record, MSR_iterator.msr.contents.reclen))
.. rubric:: Example
from future.builtins import *
from msriterator import MSR_iterator
mseedfile = "test.mseed"
for msri in MSR_iterator(filename=mseedfile, dataflag=False):
print ("{:d}: {}, reclen: {}, samples: {}, starttime: {}, endtime: {}".
format(msri.get_offset(),
msri.get_srcname(quality=False),
msri.msr.contents.reclen,
msri.msr.contents.samplecnt,
msri.get_starttime(),
msri.get_endtime()))
"""
def __init__(self, filename, startoffset=0,
reclen=-1, dataflag=0, skipnotdata=1, verbose=0,
raise_errors=True):
self.msr = clibmseed.msr_init(C.POINTER(MSRecord)())
self.msf = C.POINTER(MSFileParam)() # NULL pointer
self.file = filename
# Best guess at off_t type
self._c_off_t = C.c_long
self.fpos = self._c_off_t(0)
if startoffset != 0:
self.fpos = self._c_off_t(-startoffset)
self.reclen = reclen
self.dataflag = 1 if dataflag else 0
self.skipnotdata = 1 if skipnotdata else 0
self.verbose = verbose
self.raise_errors = raise_errors
def __iter__(self):
return self
def __next__(self):
"""
Read next record from file.
"""
errcode = clibmseed.ms_readmsr_r(C.pointer(self.msf),
C.pointer(self.msr),
self.file.encode('ascii', 'strict'),
self.reclen, C.byref(self.fpos), None,
self.skipnotdata, self.dataflag, self.verbose)
if errcode == MS_ENDOFFILE:
raise StopIteration()
if self.raise_errors:
if errcode != MS_NOERROR:
raise Exception("Error %d in ms_readmsr_r" % errcode)
return self
def __del__(self):
"""
Method for deallocating MSFileParam and MSRecord structures.
"""
errcode = clibmseed.ms_readmsr_r(C.pointer(self.msf),
C.pointer(self.msr),
None, -1, None, None, 0, 0, 0)
if errcode != MS_NOERROR:
raise Exception("Error %d in ms_readmsr_r" % errcode)
def get_srcname(self, quality=False):
"""
Return record start time
"""
srcname = C.create_string_buffer(50)
clibmseed.msr_srcname.argtypes = [C.POINTER(MSRecord),
C.POINTER(C.c_char),
C.c_int]
clibmseed.msr_srcname.restype = C.POINTER(C.c_char)
if quality:
clibmseed.msr_srcname(self.msr, srcname, 1)
else:
clibmseed.msr_srcname(self.msr, srcname, 0)
return srcname.value.decode('utf-8')
def get_starttime(self):
"""
Return record start time as UTCDateTime
"""
hptime = self.msr.contents.starttime
return UTCDateTime(hptime / HPTMODULUS)
def get_endtime(self):
"""
Return record end time as UTCDateTime
"""
hptime = clibmseed.msr_endtime(self.msr)
return UTCDateTime(hptime / HPTMODULUS)
def get_startepoch(self):
"""
Return record start time as epoch time
"""
return self.msr.contents.starttime / HPTMODULUS
def get_endepoch(self):
"""
Return record end time as epoch time
"""
hptime = clibmseed.msr_endtime(self.msr)
return hptime / HPTMODULUS
def set_offset(self, value):
"""
Set file reading position
"""
self.fpos = self._c_off_t(-value)
def get_offset(self):
"""
Return offset into file for current record
"""
return self.fpos.value
offset = property(get_offset, set_offset)