forked from pyrocko/pyrocko
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
3.5 KiB
Python
131 lines
3.5 KiB
Python
# http://pyrocko.org - GPLv3
|
|
#
|
|
# The Pyrocko Developers, 21st Century
|
|
# ---|P------/S----------~Lg----------
|
|
from __future__ import absolute_import, division
|
|
|
|
import math
|
|
import logging
|
|
|
|
from . import pile, util, io
|
|
|
|
logger = logging.getLogger('pyrocko.shadow_pile')
|
|
|
|
|
|
class NoBasePileSet(Exception):
|
|
pass
|
|
|
|
|
|
class ShadowBlock(object):
|
|
def __init__(self):
|
|
self.mtime = None
|
|
self.files = []
|
|
|
|
|
|
class ShadowPile(pile.Pile):
|
|
|
|
def __init__(self, basepile=None, tinc=360., tpad=0., storepath=None):
|
|
pile.Pile.__init__(self)
|
|
|
|
self._tinc = tinc
|
|
self._tpad = tpad
|
|
self._storepath = storepath
|
|
self._blocks = {}
|
|
|
|
if basepile is None:
|
|
basepile = pile.Pile()
|
|
|
|
self.set_basepile(basepile)
|
|
|
|
def clear(self):
|
|
for iblock in self._blocks.keys():
|
|
self._clearblock()
|
|
self._blocks = {}
|
|
|
|
def set_basepile(self, basepile):
|
|
self.clear()
|
|
self._base = basepile
|
|
|
|
def get_basepile(self):
|
|
return self._base
|
|
|
|
def set_chopsize(self, tinc, tpad=0.):
|
|
self.clear()
|
|
self._tinc = tinc
|
|
self._tpad = tpad
|
|
|
|
def set_store(self, storepath=None):
|
|
self.clear()
|
|
self._storepath = storepath
|
|
|
|
def chopper(
|
|
self, tmin=None, tmax=None, tinc=None, tpad=0., *args, **kwargs):
|
|
|
|
if tmin is None:
|
|
tmin = self.base.tmin+tpad
|
|
|
|
if tmax is None:
|
|
tmax = self.base.tmax-tpad
|
|
|
|
self._update_range(tmin, tmax)
|
|
|
|
return pile.Pile.chopper(self, tmin, tmax, tinc, tpad, *args, **kwargs)
|
|
|
|
def process(self, iblock, tmin, tmax, traces):
|
|
return traces
|
|
|
|
def _update_range(self, tmin, tmax):
|
|
imin = int(math.floor(tmin / self._tinc))
|
|
imax = int(math.floor(tmax / self._tinc)+1)
|
|
|
|
todo = []
|
|
for i in range(imin, imax):
|
|
wmin = i * self._tinc
|
|
wmax = (i+1) * self._tinc
|
|
mtime = util.gmctime(self._base.get_newest_mtime(wmin, wmax))
|
|
if i not in self._blocks or self._blocks[i].mtime != mtime:
|
|
if i not in self._blocks:
|
|
self._blocks[i] = ShadowBlock()
|
|
|
|
todo.append(i)
|
|
self._blocks[i].mtime = mtime
|
|
else:
|
|
if todo:
|
|
self._process_blocks(todo[0], todo[-1]+1)
|
|
todo = []
|
|
if todo:
|
|
self._process_blocks(todo[0], todo[-1]+1)
|
|
|
|
def _process_blocks(self, imin, imax):
|
|
pmin = imin * self._tinc
|
|
pmax = imax * self._tinc
|
|
|
|
iblock = imin
|
|
for traces in self._base.chopper(pmin, pmax, self._tinc, self._tpad):
|
|
tmin = iblock*self._tinc
|
|
tmax = (iblock+1)*self._tinc
|
|
traces = self.process(iblock, tmin, tmax, traces)
|
|
if self._tpad != 0.0:
|
|
for trace in traces:
|
|
trace.chop(tmin, tmax, inplace=True)
|
|
self._clearblock(iblock)
|
|
self._insert(iblock, traces)
|
|
iblock += 1
|
|
|
|
def _insert(self, iblock, traces):
|
|
if traces:
|
|
if self._storepath is not None:
|
|
fns = io.save(
|
|
traces, self._storepath,
|
|
format='mseed',
|
|
additional={'iblock': iblock})
|
|
|
|
self.load_files(fns, fileformat='mseed', show_progress=False)
|
|
else:
|
|
file = pile.MemTracesFile(None, traces)
|
|
self.add_file(file)
|
|
|
|
def _clearblock(self, iblock):
|
|
for file in self._blocks[iblock].files:
|
|
self.remove_file(file)
|