Earthquake catalog

Pyrocko provides access to some online earthquake catalogs via the pyrocko.client.catalog module. The recommended way to query them is through add_catalog(), which wraps the same clients but integrates the results into Squirrel’s unified, cached data access.

QuakeML import

This example shows how to read QuakeML event catalogs using load_xml(). The function get_pyrocko_events() is used to obtain events in pyrocko format. If a moment tensor is provided as [Mrr, Mtt, Mpp, Mrt, Mrp, Mtp], this is converted to [mnn, mee, mdd, mne, mnd, med]. The strike, dip and rake values appearing in the pyrocko event are calculated from the moment tensor.

from pyrocko import model
from pyrocko.io import quakeml
from pyrocko.example import get_example_data


# small catalog containing two events (data from ingv):
catalog = get_example_data('example-catalog.xml')

# read quakeml events
qml = quakeml.QuakeML.load_xml(filename=catalog)

# get pyrocko events
events = qml.get_pyrocko_events()

for event in events:
    print(event)

# save events as pyrocko catalog in the newer YAML based format
model.event.dump_events(events, filename='test_pyrocko.pf', format='yaml')

Creating QuakeML from scratch

from pyrocko.io import quakeml as q
from pyrocko.util import str_to_time as stt


table = [
    # name     time                        lat  lon   depth    mag
    ('ev0001', stt('2021-09-29 01:02:03'), 55., 120., 11000.,  5.5),
    ('ev0002', stt('2021-09-29 04:05:06'), 57., 122., 9000.,  4.0),
    ('ev0003', stt('2021-09-29 07:08:09'), 56., 121., 1200.,  4.1)]


qml = q.QuakeML(
    event_parameters=q.EventParameters(
        public_id='quakeml:test/eventParameters/test',
        event_list=[
            q.Event(
                preferred_origin_id='quakeml:test/origin/%s' % name,
                preferred_magnitude_id='quakeml:test/magnitude/%s' % name,
                public_id='quakeml:test/event/%s' % name,
                origin_list=[
                    q.Origin(
                        public_id='quakeml:test/origin/%s' % name,
                        time=q.TimeQuantity(value=time),
                        longitude=q.RealQuantity(value=lon),
                        latitude=q.RealQuantity(value=lat),
                        depth=q.RealQuantity(value=depth),
                    ),
                ],
                magnitude_list=[
                    q.Magnitude(
                        public_id='quakeml:test/magnitude/%s' % name,
                        origin_id='quakeml:test/origin/%s' % name,
                        mag=q.RealQuantity(value=magnitude),
                    )
                ],
            )
            for (name, time, lat, lon, depth, magnitude) in table
        ]
    )
)

print(qml.dump_xml())

Searching an online earthquake catalog

This example demonstrates how to query the GlobalCMT [1] database for events which occurred in 2011 in northern Chile, using add_catalog() to declare it as a data source. Query arguments common to all queries made to the catalog (here: the region and magnitude constraints) are passed via query_args, as strings. Calling update() for the time span of interest triggers the actual query, if the local copy of the catalog isn’t already up to date for it.

from pyrocko import util, model
from pyrocko.squirrel import Squirrel

tmin = util.str_to_time('2011-01-01 00:00:00')  # beginning time of query
tmax = util.str_to_time('2011-12-31 23:59:59')

sq = Squirrel()

# Add the GlobalCMT catalog as an online data source. `query_args` are
# common arguments appended to every query made to it - here used to
# restrict results to northern Chile and a minimum magnitude. Values must
# be given as strings.
sq.add_catalog('gcmt', query_args=dict(
    magmin='2.', latmin='-35.', latmax='-20.', lonmin='-76.', lonmax='-65.'))

# Refresh the local copy of the catalog for the time span of interest. This
# is when the actual query to the remote data source happens, if needed.
sq.update(tmin=tmin, tmax=tmax)

events = sq.get_events(tmin=tmin, tmax=tmax)

print('Downloaded %s events' % len(events))
print('The last one is')
print(events[-1])

# dump events to catalog
model.dump_events(events, 'northern_chile_events.txt')

Download squirrel_catalog_search.py

We expect to see the following output:

Downloaded 53 events
The last one is
--- !pf.Event
lat: -28.03
lon: -71.55
time: '2011-12-07 22:23:14.25'
depth: 22800.0
name: '201112072223A'
magnitude: 6.106838394015895
region: 'NEAR COAST OF NORTHERN C'
catalog: 'gCMT'
moment_tensor: !pf.MomentTensor
  mnn: 1.16e+17
  mee: -1.24e+18
  mdd: 1.1200000000000001e+18
  mne: 1.29e+17
  mnd: 1.61e+17
  med: 1.0900000000000001e+18
  strike1: 16.540029329929244
  dip1: 24.774772153067424
  rake1: 109.14904335232158
  strike2: 175.61123518070136
  dip2: 66.6800337700307
  rake2: 81.39111828783355
  moment: 1.622772319211786e+18
  magnitude: 6.106838394015895
duration: 5.4

The same pattern works for the other catalogs supported by add_catalog() (currently GEOFON and ISC) - just swap the catalog name and query_args, e.g. sq.add_catalog('geofon', query_args=dict(magmin='6.')).

For a one-off query where Squirrel’s indexing/caching would be unwanted overhead, the underlying clients in pyrocko.client.catalog can be used directly:

from pyrocko.client.catalog import GlobalCMT

events = GlobalCMT().get_events(
    time_range=(tmin, tmax), magmin=2.,
    latmin=-35., latmax=-20., lonmin=-76., lonmax=-65.)

Footnotes