Source code for seismic.utils.io
'''
:copyright:
The SeisMIC development team (makus@gfz-potsdam.de).
:license:
GNU Lesser General Public License, Version 3
(https://www.gnu.org/copyleft/lesser.html)
:author:
Peter Makus (makus@gfz-potsdam.de)
Created: Thursday, 8th July 2021 10:37:21 am
Last Modified: Friday, 10th February 2023 04:09:21 pm
'''
from collections.abc import Iterable
from obspy.core.utcdatetime import UTCDateTime
from obspy.core.trace import Stats
from scipy.io import loadmat
from seismic.correlate.stats import CorrStats
from seismic.correlate.stream import CorrTrace, CorrBulk
[docs]def flatten(x):
""" Return the flattened version of the input array x
This funciton works with all :class:`~collections.Iterable` that can be
nested in an irregular fashion.
:type x: :class:`~collections.Iterable`
:param: Iterable to be flattened
:rtype: list
:return: x as a flattened list
.. rubric: Example
>>> L=[[[1, 2, 3], [4, 5]], 6]
>>> flatten(L)
[1, 2, 3, 4, 5, 6]
"""
result = []
for el in x:
if isinstance(el, Iterable) and not isinstance(el, str):
result.extend(flatten(el))
else:
result.append(el)
return result
[docs]def flatten_recarray(x):
""" Flatten a recarray
"""
flat_dict = {}
if hasattr(x, 'dtype'):
if hasattr(x.dtype, 'names'):
if x.dtype.names is not None:
for name in x.dtype.names:
field = flatten(x[name])
if field != []:
flat_dict.update({name: field[0]})
else:
flat_dict.update({name: field})
return flat_dict
return x
zerotime = UTCDateTime(1971, 1, 1)
[docs]def mat_to_corrtrace(mat: dict) -> CorrTrace:
"""
Reads in a correlation dictionary created with the old (i.e., python2)
miic and translates it into a :class:`~seismic.correlate.stream.CorrTrace`
object.
:param mat: dictionary as produced by :func:`scipy.io.loadmat`
:type mat: dict
:return: A Correlation Trace
:rtype: CorrTrace
"""
for key in mat:
if mat[key] is not None:
flat_var = flatten_recarray(mat[key])
mat.update({key: flat_var})
start_lag = UTCDateTime(mat['stats']['starttime']) - zerotime
end_lag = UTCDateTime(mat['stats']['endtime']) - zerotime
if not isinstance(mat['stats_tr1']['location'], str):
mat['stats_tr1'].update({'location': '-'})
if not isinstance(mat['stats_tr2']['location'], str):
mat['stats_tr2'].update({'location': '-'})
ctr = CorrTrace(
mat['corr_trace'].flatten(), Stats(mat['stats_tr1']),
Stats(mat['stats_tr2']), start_lag=start_lag, end_lag=end_lag)
return ctr
[docs]def corrmat_to_corrbulk(path: str) -> CorrBulk:
"""
Reads in a correlation .mat file created with the old (i.e., python2)
miic and translates it into a :class:`~seismic.correlate.stream.CorrTrace`
object.
:param path: Path to file
:type path: str
:return: A Correlation Bulk object
:rtype: CorrBulk
:warning: This reads both stacks and subdivisions into the same object.
"""
mat = loadmat(path)
for key in mat:
if mat[key] is not None:
flat_var = flatten_recarray(mat[key])
mat.update({key: flat_var})
stats = CorrStats()
start_lag = UTCDateTime(mat['stats']['starttime']) - zerotime
data = mat.pop('corr_data')
corr_start = [UTCDateTime(t) for t in mat['time']]
mat['stats'].pop('starttime')
stats.update(mat['stats'])
stats.update({'start_lag': start_lag, 'corr_start': corr_start})
return CorrBulk(data, stats)