Squirrel processing pipelines (mantras)¶
Warning
Mantras and operators are experimental. Their interfaces and configuration formats may still change.
Operators derive new data from the data available through a
Squirrel, e.g. by removing the instrument
response or by rotating the components of a sensor. Each operator takes one
or more inputs (a Squirrel or other operators) and can be queried like a
Squirrel itself, e.g. with get_waveforms(), get_channels() or
get_codes(). Processing happens on demand, when data is requested.
A mantra is a named chain of operators, configured in a YAML file. Mantras
can be used from the command line, e.g. with squirrel mantra or
squirrel service, and from Python scripts.
Operators¶
Some of the available operators:
Restitution– remove the instrument response, converting to displacement, velocity or acceleration.ToENZ,ToTRZ,ToLQT– rotate the components of each sensor to East-North-Up, Transverse-Radial-Up or ray-based Longitudinal-Transverse-SH coordinates.MultiSpectrogramOperator– compute multi-resolution spectrograms, seesquirrel spectrogram.
Derived data is identified by its codes. The basic operators above append a
short tag to the extra code (the fifth, non-standard, element of the codes),
e.g. Rv for response restitution to velocity, or Tenz for rotation to
ENZ. A vertical channel GR.GRA1..BHZ. processed with the mantra below
becomes GR.GRA1..BHZ.RvTenz. How the output codes are formed can be
configured with codes templates, see Codes templates.
Note
Code patterns with four elements, like GR.GRA1..BHZ, only match
codes with an empty extra code. To select derived data, append .*,
e.g. --codes 'GR.GRA1..BHZ.*'.
Note
Mini-SEED cannot store the extra code, and it limits the length of the
other codes to 2 (network), 5 (station), 2 (location) and 3 (channel)
characters. Writing derived waveforms with an extra code or with longer
codes to Mini-SEED fails with an error. Store them in another format
(e.g. YAFF), or rename them first, e.g. with squirrel jackseis
--rename-extra '', keeping in mind that they can then no longer be told
apart from the original data.
Configuration¶
Example mantra configuration file velocity.yaml, restituting to velocity
and rotating to East-North-Up components:
--- !squirrel.Mantra
name: velocity
operators:
- !squirrel.ops.Restitution
quantity: velocity
frequency_min: 0.1
frequency_max: 5.0
- !squirrel.ops.ToENZ {}
The operators are chained in the given order: the first operator gets its input from the Squirrel, each following operator from the previous one.
Codes templates¶
Each operator has a codes_projection attribute, which determines what
input it acts on, which inputs are processed together and how the output codes
are named. It contains a template string in Python’s str.format syntax.
The default template of
Restitution, for example, is:
{i.network}.{i.station}.{i.location}.{i.channel}.{i.extra}R{o.quantity}
Placeholders {i.*} are replaced by the elements of the input codes:
network, station, location, channel, extra, and
channel_no_component, the channel code without its last character.
Placeholders {o.*} are replaced by the attributes of the operator’s
outlets (e.g. quantity, or system and component for rotations),
and by the operator’s name and the mantra name.
The template also defines which input codes are processed together (fan-in):
all input codes giving the same result, with the {o.*} placeholders left
empty, form one group. For the rotation operators, the default template uses
{i.channel_no_component}, so that the three components of a sensor form
one group. An operator with several outlets produces one output per outlet
(fan-out), e.g. the three output components of a rotation. To group
differently than the template suggests, an explicit group_by template can
be given. With include and exclude, lists of codes patterns, the
operator can be restricted to part of its input.
squirrel mantra show lists the resulting mappings, e.g. for the rotation
in the example above:
GR.GRA1..{BHE,BHN,BHZ}.RvTenz <- GR.GRA1..{BHE,BHN,BHZ}.Rv
Example: restitute only vertical components and mark the output with the mantra name instead of the default tag:
--- !squirrel.Mantra
name: vel
operators:
- !squirrel.ops.Restitution
quantity: velocity
frequency_min: 0.1
frequency_max: 5.0
codes_projection: !squirrel.ops.CodesProjection
template: '{i.network}.{i.station}.{i.location}.{i.channel}.{o.mantra}'
include: ['*.*.*.*Z.*']
This gives mappings like GR.GRA1..BHZ.vel <- GR.GRA1..BHZ..
Example: compute spectrograms of all stations and average them per channel, i.e. over all stations of an array:
--- !squirrel.Mantra
name: specsum
operators:
- !squirrel.ops.MultiSpectrogramOperator {}
- !squirrel.ops.CarpetSum
normalize: true
codes_projection: !squirrel.ops.CodesProjection
template: '.SUM..{i.channel}.{i.extra}'
The template of the second operator does not contain the station, so all stations with the same channel end up in one group:
.SUM..BHZ.MS <- GR.{GRA1,GRA2,...,GRC4}..BHZ.MS
Note that derived codes become part of stored file names and of the codes seen by later processing steps. Changing a template later therefore changes how existing results are identified.
Command line¶
To see which input codes are mapped to which output codes:
squirrel mantra show --mantra velocity.yaml --add data/raw meta/stations.xml
The processed data can be viewed in the web browser with squirrel
service, where it appears as a separate gate, named like the mantra:
squirrel service --mantra velocity.yaml --add data/raw meta/stations.xml
Mantras which produce carpets (e.g. spectrograms) can be applied to a whole
dataset with squirrel mantra process, storing the results in files.
Example: compute spectrograms of the vertical components of some stations for one day, processing in batches of one hour:
--- !squirrel.Mantra
name: spec
operators:
- !squirrel.ops.MultiSpectrogramOperator {}
squirrel mantra process --mantra spec.yaml \
--add data/raw meta/stations.xml \
--tmin 2017-09-03 --tmax 2017-09-04 --tinc 3600 \
--codes 'GR.GRA*..BHZ.*' \
--out data/spectrograms/spec
The --codes patterns are matched against the output codes of the mantra,
e.g. GR.GRA1..BHZ.MS, so the .* for the extra code is needed. When
stored, the extra element of the codes is replaced by the mantra name, e.g.
GR.GRA1..BHZ.spec. Use --append or --merge to add results to
existing files, e.g. when processing a dataset piece by piece. The results
can be viewed with squirrel service --add data/spectrograms/spec.
Python¶
from pyrocko import squirrel, guts
sq = squirrel.Squirrel()
sq.add(['data/raw', 'meta/stations.xml'])
mantra = guts.load(filename='velocity.yaml')
mantra.setup(sq)
tmin, tmax = sq.get_time_span(['waveform'])
# Query processed data from the last operator of the chain.
traces = mantra.outlet.get_waveforms(
tmin=tmin, tmax=tmin+3600., codes='GR.GRA1.*.*.*')
Operators can also be created and connected directly in Python, without a mantra:
rest = squirrel.Restitution(
quantity='velocity', frequency_min=0.1, frequency_max=5.0)
rest.add_input(sq)
traces = rest.get_waveforms(tmin=tmin, tmax=tmin+3600.)
See pyrocko.squirrel.operators.base and
pyrocko.squirrel.mantra for the API reference.