IRIS-EarthScope Short Course

Bloomington/IN, August 2015

Python/ObsPy Introduction


image by Matthias Meschede

ObsPy Introduction

In this very short introduction to ObsPy we will see how we can start from scratch to acquire time series data (aka waveforms) of the ground shaking resulting from earthquakes, recorded at seismometer stations. Many global seismometer recordings are free to be downloaded by everybody. We will also see how these data can be handled in Python using the ObsPy framework.

We will:

  1. fetch information on earthquakes (aka events) hosted by international data centers
  2. fetch information on seismometer stations that recorded a particular earthquake
  3. fetch waveform data of the earthquake waves recorded at that station
  4. convert the raw recorded data to physical units (aka instrument correction)

Again, please execute the following cell, it contains a few adjustments to the notebook.

In [1]:
%matplotlib inline
from __future__ import print_function
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot')
plt.rcParams['figure.figsize'] = 12, 8

1. Event Metadata

  • several different protocols are implemented in ObsPy to connect to all important seismological data centers
  • the most important protocol are FDSN web services (other protocols work very similar)

  • the "get_events()" method has many ways to restrict the search results (time, geographic, magnitude, ..)

In [2]:
from obspy.fdsn import Client

client = Client("IRIS")

catalog = client.get_events(minmagnitude=8.5, starttime="2010-01-01")

print(catalog)
catalog.plot();
3 Event(s) in Catalog:
2012-04-11T08:38:37.800000Z |  +2.238,  +93.014 | 8.6 MW
2011-03-11T05:46:23.200000Z | +38.296, +142.498 | 9.1 MW
2010-02-27T06:34:13.330000Z | -36.148,  -72.933 | 8.8 MW
  • event/earthquake metadata is bundled in a Catalog object, which is a collection (~list) of Event objects
  • Event objects are again collections of other resources (origins, magnitudes, picks, ...)
  • the nested ObsPy Event class structure (Catalog/Event/Origin/Magnitude/FocalMechanism/...) is closely modelled after QuakeML (the international standard exchange format for event metadata)
In [3]:
print(catalog)
3 Event(s) in Catalog:
2012-04-11T08:38:37.800000Z |  +2.238,  +93.014 | 8.6 MW
2011-03-11T05:46:23.200000Z | +38.296, +142.498 | 9.1 MW
2010-02-27T06:34:13.330000Z | -36.148,  -72.933 | 8.8 MW
In [4]:
event = catalog[1]
print(event)
Event:	2011-03-11T05:46:23.200000Z | +38.296, +142.498 | 9.1 MW

	        resource_id: ResourceIdentifier(id="smi:service.iris.edu/fdsnws/event/1/query?eventid=3279407")
	         event_type: u'earthquake'
	---------
	 event_descriptions: 1 Elements
	            origins: 1 Elements
	         magnitudes: 1 Elements
In [ ]:
# you can use Tab-Completion to see what attributes/methods the event object has:
event.
origin.
In [5]:
from obspy import readEvents

catalog2 = readEvents("./data/events_unterhaching.xml")
print(catalog2)

# these events contain picks, too
print(catalog2[0].picks[0])
7 Event(s) in Catalog:
2010-05-27T16:24:31.802036Z | +48.048,  +11.646 | 2.08662460284 Ml
2010-05-27T16:43:49.542034Z | +48.048,  +11.646 | 1.4954033383 Ml
2013-04-16T21:51:42.648944Z | +48.046,  +11.643 | 1.96765657554 Ml
2013-04-16T21:51:47.556942Z | +48.045,  +11.643 | 1.88540591771 Ml
2013-04-16T22:00:01.861996Z | +48.047,  +11.643 | 1.31056358704 Ml
2013-04-16T22:15:28.557771Z | +48.046,  +11.643 | 1.76859128731 Ml
2013-04-18T18:15:57.733615Z | +48.045,  +11.642 | 1.57623047808 Ml
Pick
	 resource_id: ResourceIdentifier(id="smi:de.erdbeben-in-bayern/pick/1341b3dd-21de-4c6c-92db-40bfe76e8950")
	        time: UTCDateTime(2010, 5, 27, 16, 24, 33, 315000) [uncertainty=0.01]
	 waveform_id: WaveformStreamID(network_code='BW', station_code='UH1', channel_code='EHZ', location_code='')
	  phase_hint: 'P'
	    polarity: u'negative'

2. Station Metadata

  • again, several different protocols are implemented in ObsPy to connect to all important seismological data centers
  • the most important protocol are FDSN web services (other protocols work similar)
  • the "get_stations()" method has many ways to restrict the search results (time, geographic, station names, ..)
In [6]:
t = event.origins[0].time
print(t)

inventory = client.get_stations(
    network="TA",
    starttime=t, endtime=t+10)

print(inventory)
inventory.plot(projection="local");
2011-03-11T05:46:23.200000Z
Inventory created at 2015-08-03T17:13:49.000000Z
	Created by: IRIS WEB SERVICE: fdsnws-station | version: 1.1.16
		    http://service.iris.edu/fdsnws/station/1/query?endtime=2011-03-11T0...
	Sending institution: IRIS-DMC (IRIS-DMC)
	Contains:
		Networks (1):
			TA
		Stations (438):
			TA.034A (Hebronville, TX, USA)
			TA.035A (Encino, TX, USA)
			TA.035Z (Hargill, TX, USA)
			TA.109C (Camp Elliot, Miramar, CA, USA)
			TA.121A (Cookes Peak, Deming, NM, USA)
			TA.133A (Hamilton Ranch, Breckenridge, TX, USA)
			TA.134A (White-Moore Ranch, Lipan, TX, USA)
			TA.135A (Vickery Place, Crowley, TX, USA)
			TA.136A (Ennis, TX, USA)
			TA.137A (Heron Place, Grand Saline, TX, USA)
			TA.138A (Matatall Enterprise, Big Sandy, TX, USA)
			TA.139A (Bunkhouse Ranch, Marshall, TX, USA)
			TA.140A (Cam and Jess, Hughton, LA, USA)
			TA.141A (Papa Simpson, Farm, Arcadia, LA, USA)
			TA.142A (Monroe, LA, USA)
			TA.143A (Socs Landing, Pioneer, LA, USA)
			TA.214A (Organ Pipe National Monument, Ajo, AZ, USA)
			TA.233A (Rising Star, TX, USA)
			TA.234A (Clairette, TX, USA)
			TA.236A (Katherine and Luke Keathley, Corsicana, TX, USA)
			TA.237A (Washetta, Montalba, TX, USA)
			TA.238A (Jacksonville, TX, USA)
			TA.239A (Gary, TX, USA)
			TA.240A (Hunter Patterson, Mansfield, LA, USA)
			TA.241A (Mo Tay, Goldonna, LA, USA)
			TA.242A (Grayson, LA, USA)
			TA.243A (Waterproof, LA, USA)
			TA.333A (Richland Springs, TX, USA)
			TA.334A (Lometa, TX, USA)
			TA.335A (Moody, TX, USA)
			TA.336A (Riesel, TX, USA)
			TA.337A (Centerville, TX, USA)
			TA.338A (Crockett, TX, USA)
			TA.339A (Huntington, TX, USA)
			TA.340A (Bronson, TX, USA)
			TA.341A (Kurthwood, LA, USA)
			TA.342A (Flagon Creek Properties, Pineville, LA, USA)
			TA.343A (Vidalia, LA, USA)
			TA.433A (Art, TX, USA)
			TA.434A (Burnet, TX, USA)
			TA.435B (Jarrell, TX, USA)
			TA.436A (Wall Ranch, Gause, TX, USA)
			TA.437A (Phantom Ranch, North Zulch, TX, USA)
			TA.438A (Sam Houston State University, Huntsville, TX, USA)
			TA.439A (Center Grove, Livingston, TX, USA)
			TA.440A (Kirbyville, TX, USA)
			TA.441A (DeRidder, LA, USA)
			TA.442A (Mamou, LA, USA)
			TA.443A (Delano Plantation, Melville, LA, USA)
			TA.444A (Pine Grove, LA, USA)
			TA.445A (Amite, LA, USA)
			TA.533A (Kerrville, TX, USA)
			TA.534A (Blanco, TX, USA)
			TA.535A (Dale, TX, USA)
			TA.536A (Bastrop, TX, USA)
			TA.537A (Green Hill Farm, Brenham, TX, USA)
			TA.538A (Harpers Horsepen, Conroe, TX, USA)
			TA.539A (Cross D Ranch, Liberty, TX, USA)
			TA.540A (Vidor, TX, USA)
			TA.541A (Lake Charles, LA, USA)
			TA.542A (Morse, LA, USA)
			TA.543A (St. Martinville, LA, USA)
			TA.544A (White Castle, LA, USA)
			TA.545A (Edgard, LA, USA)
			TA.633A (Saathoff Ranch, Hondo, TX, USA)
			TA.634A (China Grove, San Antonio TX, USA)
			TA.635A (Leesville, TX, USA)
			TA.636A (Smothers Creek Ranch, Halletsville, TX, USA)
			TA.637A (Eagle Lake, TX, USA)
			TA.638A (Rosharon, TX, USA)
			TA.733A (Divot King Ranch, Dilley, TX, USA)
			TA.734A (La Parita Creek, Jourdanton, TX, USA)
			TA.735A (Kenedy, TX, USA)
			TA.736A (Circle Diamond K Ranch, Victoria, TX, USA)
			TA.737A (Port Lavaca, TX, USA)
			TA.738A (Farr-Stevens Ranch, Sargent, TX, USA)
			TA.832A (Faith Ranch, Carrizo Springs, TX, USA)
			TA.833A (Chaparral WMA, Artesia Wells, TX, USA)
			TA.834A (Tilden, TX, USA)
			TA.835A (Beeville, TX, USA)
			TA.933A (Laredo, TX, USA)
			TA.934A (Benavides, TX, USA)
			TA.936A (North Padre Island, Corpus Christi, TX, USA)
			TA.A04D (Lummi Island, WA, USA)
			TA.A25A (Svangstu Ranch, Noonan, ND, USA)
			TA.A26A (Wade Farm, Kenmare, ND, USA)
			TA.A27A (Ledoux Ranch, Antler, ND, USA)
			TA.A28A (Rude Farm, Bottineau, ND, USA)
			TA.A29A (Manning Farm, Rocklake, ND, USA)
			TA.A30A (Hoffart Farm, Langdon, ND, USA)
			TA.A31A (Linda, St. Vincent, MN, USA)
			TA.A32A (Rocking H Ranch, Lancaster, MN, USA)
			TA.A33A (Warroad, MN, USA)
			TA.ABTX (Abilene, Hawley, TX, USA)
			TA.B05D (Stanwood, WA, USA)
			TA.B25A (Knox Farm, Ray, ND, USA)
			TA.B26A (Jensen Ranch, Palermo, ND, USA)
			TA.B27A (Peters Farms, Glenburn, ND, USA)
			TA.B28A (Dugan Ranch, Towner, ND, USA)
			TA.B29A (Wagenman Farm, Cando, ND, USA)
			TA.B30A (Myrvik Farm, Edmore, ND, USA)
			TA.B31A (Greenbush Farm, Park River, ND, USA)
			TA.B32A (Ashes, Strandquist, MN, USA)
			TA.B33A (Robert and Kassanda Mosher, Grygla, MN, USA)
			TA.B34A (Aery, Baudette, MN, USA)
			TA.B35A (Bob, Littlefork, MN, USA)
			TA.BGNE (Belgrade, NE, USA)
			TA.C06D (Leavenworth, WA, USA)
			TA.C25A (Freed Ranch, Watford, ND, USA)
			TA.C26A (Wahner Farm, Parshall, ND, USA)
			TA.C27A (Sayler Ranch, Douglas, ND, USA)
			TA.C28A (Hausauer Farms, Kief, ND, USA)
			TA.C30A (Mose, Pekin, ND, USA)
			TA.C31A (Landman Farms, Northwood, ND, USA)
			TA.C32A (Crookston, MN, USA)
			TA.C33A (Trail, MN, USA)
			TA.C34A (RKJ Ranch, Bemidji, MN, USA)
			TA.C35A (Jirik Farms, Max, MN, USA)
			TA.C36A (Pine Crest Farm, Angora, MN, USA)
			TA.C37A (Embarrass, MN, USA)
			TA.C38A (Sawbill Land. Superior Nat. Forest USFS, MN, USA)
			TA.C39A (Grand Marais, MN, USA)
			TA.D03D (Eldon, WA, USA)
			TA.D04D (Lakebay, WA, USA)
			TA.D25A (Fairfield, ND, USA)
			TA.D26A (Manning, ND, USA)
			TA.D27A (Center, ND, USA)
			TA.D28A (Regan, ND, USA)
			TA.D29A (Pettibone, Tappen, ND, USA)
			TA.D30A (Buchanan, ND, USA)
			TA.D31A (Mcclaflin, Tower City, ND, USA)
			TA.D32A (Dogwood Acres, Gardner, ND, USA)
			TA.D33A (AnnSam, Waubun, MN, USA)
			TA.D34A (Park Rapids, MN, USA)
			TA.D35A (Remer, MN, USA)
			TA.D36A (Goodland, MN, USA)
			TA.D37A (Cotton, MN, USA)
			TA.E04D (Cinebar, WA, USA)
			TA.E25A (Miller Ranch, Amidon, ND, USA)
			TA.E26A (Carlson Angus Ranch, Regent, ND, USA)
			TA.E27A (Carson, ND, USA)
			TA.E28A (Huff, ND, USA)
			TA.E29A (Napoleon, ND, USA)
			TA.E30A (Jud, ND, USA)
			TA.E31A (Nome, ND, USA)
			TA.E32A (Braaten, Kindred, ND, USA)
			TA.E33A (Westby DABS, Erhard, MN, USA)
			TA.E34A (Wadena, MN, USA)
			TA.E35A (Pequot Lakes, MN, USA)
			TA.E36A (McGregor, MN, USA)
			TA.E37A (Wrenshall, MN, USA)
			TA.F04D (Rainier, OR, USA)
			TA.F05D (White Salmon, WA, USA)
			TA.F25A (Bowman, SD, USA)
			TA.F26A (Lodgepole, SD, USA)
			TA.F27A (Lemmon, SD, USA)
			TA.F28A (McLaughlin, SD, USA)
			TA.F29A (Eureka, SD, USA)
			TA.F30A (Leola, SD, USA)
			TA.F31A (Hecla, SD, USA)
			TA.F32A (Veblen, SD, USA)
			TA.F33A (5 Mile Ranch, Herman, MN, USA)
			TA.F34A (Alexandria, MN, USA)
			TA.F35A (Swanville, MN, USA)
			TA.F36A (Milaca, MN, USA)
			TA.G03D (McMinnville, OR, USA)
			TA.G05D (Wamic, OR, USA)
			TA.G25A (Newell, SD, USA)
			TA.G26A (Maurine, SD, USA)
			TA.G27A (Dupree, SD, USA)
			TA.G28A (Parade, SD, USA)
			TA.G29A (Hoven, SD, USA)
			TA.G30A (Faulkton, SD, USA)
			TA.G31A (Conde, SD, USA)
			TA.G32A (Webster, SD, USA)
			TA.G33A (Ortonville, MN, USA)
			TA.G34A (Benson, MN, USA)
			TA.G35A (Watkins, MN, USA)
			TA.G36A (St. Michael, MN, USA)
			TA.H04D (Lebanon, OR, USA)
			TA.H17A (Grant Village (NPS), Yellowstone Nt. Park, WY, USA)
			TA.H25A (Fruitdale, SD, USA)
			TA.H26A (Fairpoint, SD, USA)
			TA.H27A (Howes, SD, USA)
			TA.H28A (Mission Ridge, SD, USA)
			TA.H29A (Onida, SD, USA)
			TA.H31A (Wolsey, SD, USA)
			TA.H32A (Carlson Farm, Erwin, SD, USA)
			TA.H33A (Prehn Over North, Clear Lake, SD, USA)
			TA.H34A (Spellman Lake, Hanley Falls, MN, USA)
			TA.H35A (Sunnyside Ranch, Fairfax, MN, USA)
			TA.H36A (Jessenland, Henderson, MN, USA)
			TA.H37A (Dierke Farm, Cannon Falls, MN, USA)
			TA.I02D (Swisshome, OR, USA)
			TA.I03D (Drain, OR, USA)
			TA.I04A (Tendick Farm, Oakridge, OR, USA)
			TA.I05D (Terrebonne, OR, USA)
			TA.I25A (Rochford, SD, USA)
			TA.I26A (New Underwood, SD, USA)
			TA.I27A (Quinn, SD, USA)
			TA.I28A (Midland, SD, USA)
			TA.I29A (Vivian, Onida, SD, USA)
			TA.I30A (Oacoma, SD, USA)
			TA.I31A (Royce, Wessington Springs, SD, USA)
			TA.I32A (Karley and Nick, Howard, SD, USA)
			TA.I33A (Coleman, SD, USA)
			TA.I34A (Hadley, MN, USA)
			TA.I35A (Creekview Farms, Bingham Lake, MN, USA)
			TA.I36A (Fitzsimmons Farm, Good Thunder, MN, USA)
			TA.I37A (Lemond, Waseca, MN, USA)
			TA.I38A (Scanlan Farm, Eyota, MN, USA)
			TA.J01D (Myrtle Point, OR, USA)
			TA.J04D (Umpqua National Forest, Toketee, OR, USA)
			TA.J05D (Fort Rock, OR, USA)
			TA.J25A (Sunshine Ranch, Edgemont, SD, USA)
			TA.J26A (Sides Ranch, Smithwick, SD, USA)
			TA.J27A (Elkhorn Farm, Martin, SD, USA)
			TA.J28A (Allard Ranch, Norris, SD, USA)
			TA.J29A (Okreek, SD, USA)
			TA.J30A (Dallas, SD, USA)
			TA.J31A (Geddes, SD, USA)
			TA.J32A (Parkston, SD, USA)
			TA.J33A (Davis, SD, USA)
			TA.J34A (George, IA, USA)
			TA.J35A (Milford, IA, USA)
			TA.J36A (Seneca 1, Swea City, IA, USA)
			TA.J37A (Redenius Farm, Forest, IA, USA)
			TA.J38A (Wedel Dairy, Riceville, IA, USA)
			TA.K02D (Willamette Meridian, OR, USA)
			TA.K04D (Chiloquin, OR, USA)
			TA.K22A (Casper, WY, USA)
			TA.K28A (Ten Mile Ranch, Cody, NE, USA)
			TA.K29A (Lazy Trails Angus Ranch, Wood Lake, NE, USA)
			TA.K30A (Basset, NE, USA)
			TA.K31A (O'Neill, NE, USA)
			TA.K32A (Verdigre, NE, USA)
			TA.K33A (Hardington, NE, USA)
			TA.K34A (Le Mars, IA, USA)
			TA.K35A (Storm Lake, IA, USA)
			TA.K36A (Gilmore City, IA, USA)
			TA.K37A (Belmond, IA, USA)
			TA.K38A (Parkersburg, IA, USA)
			TA.KMSC (Kings Mountain, Blacksburg, SC, USA)
			TA.KSCO (Kaye Shedlock's, Cheyenne Wells, CO, USA)
			TA.L02D (Cave Junction, OR, USA)
			TA.L04D (Klamath Falls, OR, USA)
			TA.L28A (Connealy Angus Ranch, Whitman, NE, USA)
			TA.L29A (Maesberg Ranch, Thedford, NE, USA)
			TA.L30A (Spencer Herefords Ranch, Brewster, NE, USA)
			TA.L31A (Butterfield Farm, Chambers, NE, USA)
			TA.L32A (Elgin, NE, USA)
			TA.L33A (Hoskins, NE, USA)
			TA.L34A (Svendsen Farm, Lyons, NE, USA)
			TA.L35A (Bielow Farm, Ricketts, IA, USA)
			TA.L36A (Harm Buss Farm, Glidden, IA, USA)
			TA.L37A (Phoenix Point, Boone, IA, USA)
			TA.L38A (Oak Wood Farm, Albion, IA, USA)
			TA.M02C (Callahan, CA, USA)
			TA.M04C (Macdoel, CA, USA)
			TA.M28A (Bar X Bar Ranch, Keystone, NE, USA)
			TA.M29A (Burnside Ranch, Stapleton, NE, USA)
			TA.M30A (Dale-Ortello Valley, Anselmo, NE, USA)
			TA.M31A (Lambtecht Ranch, Loup City, NE, USA)
			TA.M33A (Taylor Creek Farms, Clarkson, NE, USA)
			TA.M34A (Aspy Farms, Fremont, NE, USA)
			TA.M35A (Neola, IA, USA)
			TA.M36A (Felix, Anita, IA, USA)
			TA.M37A (Trindle Farm, Earlham, IA, USA)
			TA.M38A (Pleasantville, IA, USA)
			TA.M54A (Oil Creek State Park, Oil City, PA, USA)
			TA.MDND (Maddock, ND, USA)
			TA.MSTX (Muleshoe, TX, USA)
			TA.N02D (Trinity Center, CA, USA)
			TA.N23A (Red Feather Lakes, CO, USA)
			TA.N28A (Pribbeno Ranch, Imperial, NE, USA)
			TA.N29A (Votaw Ranch, Wellfleet, NE, USA)
			TA.N30A (Hueftle Ranch, Cozad, NE, USA)
			TA.N31A (Bailey Ranch, Gibbon, NE, USA)
			TA.N32A (Stulken Farm, Doniphan, NE, USA)
			TA.N33A (J Bar K, Exeter, NE, USA)
			TA.N34A (Lincoln, NE, USA)
			TA.N35A (Tabor, IA, USA)
			TA.N36A (Muff Farm, Clarinda, IA, USA)
			TA.N37A (Lee Faris, Mount Ayr, IA, USA)
			TA.N38A (Joe's South Fork Station, Corydon, IA, USA)
			TA.N39A (Derby Farms, Drakesville, IA, USA)
			TA.N54A (Moraine State Park, Portersville, PA, USA)
			TA.N59A (State Game Land 141, Hazleton, PA, USA)
			TA.O02D (Mt. Diablo Meridian, CA, USA)
			TA.O03D (Paynes Creek, CA, USA)
			TA.O20A (White River City, CO, USA)
			TA.O28A (Krutsinger Ranch, Parks, NE, USA)
			TA.O29A (4D Ranch, Culbertson, NE, USA)
			TA.O30A (M W Ranch, Wilsonville, NE, USA)
			TA.O31A (Woollen Ranch, Alma, NE, USA)
			TA.O32A (Brockman Farm, Red Cloud, NE, USA)
			TA.O33A (Hebron, NE, USA)
			TA.O34A (Beatrice, NE, USA)
			TA.O35A (Humboldt, NE, USA)
			TA.O36A (Bolckow, MO, USA)
			TA.O37A (Wolven Farm, McFall, MO, USA)
			TA.O38A (Galt, MO, USA)
			TA.O39A (Kirksville, MO, USA)
			TA.O40A (La Belle, MO, USA)
			TA.O56A (Blue Knob State Park, Imler, PA, USA)
			TA.P28A (Satin Francis, KS, USA)
			TA.P29A (Atwood, KS, USA)
			TA.P30A (Selden, KS, USA)
			TA.P31A (Stockton, KS, USA)
			TA.P32A (Huiting Farm, Downs, KS, USA)
			TA.P33A (Williams Farm, Concordia, KS, USA)
			TA.P34A (Walnut Farm, Randolph, KS, USA)
			TA.P35A (Duane Minner, Soldier, KS, USA)
			TA.P36A (Good Intent, Atchison, KS, USA)
			TA.P37A (Lathrop, MO, USA)
			TA.P38A (Dawn, MO, USA)
			TA.P39A (Salisbury, MO, USA)
			TA.P40A (Paris, MO, USA)
			TA.Q24A (Divide, CO, USA)
			TA.Q28A (Sharon Springs, KS, USA)
			TA.Q29A (Oakley, KS, USA)
			TA.Q30A (Quinter, KS, USA)
			TA.Q31A (Ellis, KS, USA)
			TA.Q32A (Meitler Ranch, Lucas, KS, USA)
			TA.Q33A (Connelly Farm, Tescott, KS, USA)
			TA.Q34A (Chapman, KS, USA)
			TA.Q35A (Mercer Eighty, Eskridge, KS, USA)
			TA.Q36A (Arnold C. Orvedal, Lecompton, KS, USA)
			TA.Q37A (Longview Farm, Lee's Summit, MO, USA)
			TA.Q38A (Cook's Store, Concordia, MO, USA)
			TA.Q39A (Willow Grove Farm, Nelson, MO, USA)
			TA.Q40A (Laux Farm, Auxvasse, MO, USA)
			TA.R11A (Troy Canyon, Currant, NV, USA)
			TA.R28A (Tribune, KS, USA)
			TA.R29A (Marienthal, KS, USA)
			TA.R30A (Dighton, KS, USA)
			TA.R31A (Burdett, KS, USA)
			TA.R32A (Long Quarter, Great Bend, KS, USA)
			TA.R33A (Olander Ranch, Little River, KS, USA)
			TA.R34A (Isabella, Hillsboro, KS, USA)
			TA.R35A (Emporia Municipal Airport, Emporia, KS, USA)
			TA.R36A (Gordon, Harris, KS, USA)
			TA.R37A (Teagarden Farms, La Cygne, KS, USA)
			TA.R38A (Fenwick Farm, Montrose, MO, USA)
			TA.R39A (Chumby, Stover, MO, USA)
			TA.R40A (Maddie's Station, St. Elizabeth, MO, USA)
			TA.S22A (4UR Ranch, Creede, CO, USA)
			TA.S28A (Manter, KS, USA)
			TA.S29A (Ulysses, KS, USA)
			TA.S30A (Montezuma, KS, USA)
			TA.S32A (Newby Ranch, Pratt, KS, USA)
			TA.S33A (Kaszmaul Farm, Murdock, KS, USA)
			TA.S34A (Willow Spring Farm, Andover, KS, USA)
			TA.S35A (Otter Creek Ranch, Eureka, KS, USA)
			TA.S36A (Lake Cedric, Chanute, KS, USA)
			TA.S37A (Fort Scott, KS, USA)
			TA.S38A (Stockton, MO, USA)
			TA.S39A (Bolivar, MO, USA)
			TA.S40A (Lebanon, MO, USA)
			TA.SFIN (Lafayette, IN, USA)
			TA.SPMN (Marine on St. Croix, MN, USA)
			TA.SUSD (Miller, SD, USA)
			TA.T25A (Trinidad, CO, USA)
			TA.T29A (Hugoton, KS, USA)
			TA.T30A (Plains, KS, USA)
			TA.T31A (Randall Ranch, Ashland, KS, USA)
			TA.T32A (Huddler Ranch, Lake City, KS, USA)
			TA.T33A (Patterson Ranch, Waldron, KS, USA)
			TA.T34A (McClaskey Farms, Geuda Springs, KS, USA)
			TA.T35A (Sooner Cattle Company, Foraker, OK, USA)
			TA.T36A (Boggs Farm, Caney, KS, USA)
			TA.T37A (Cheneyville 1850, Columbus, KS, USA)
			TA.T38A (Diamond, MO, USA)
			TA.T39A (Clever, MO, USA)
			TA.T40A (Mansfield, MO, USA)
			TA.TIGA (Tifton, GA, USA)
			TA.TPFO (Pinon Flats, CA, USA)
			TA.TUL1 (Leonard, OK, USA)
			TA.U29A (Oasis Ranch, Spearman, TX, USA)
			TA.U30A (WK&E Inc., Balko, OK, USA)
			TA.U31A (Nine Bar Ranch, Gage, OK, USA)
			TA.U32A (Winter Ranch, Mooreland, OK, USA)
			TA.U33A (Lingo Farm, Meno, OK, USA)
			TA.U34A (Anderson Ranch, Garber, OK, USA)
			TA.U35A (Pawnee, OK, USA)
			TA.U36A (Oologah, OK, USA)
			TA.U37A (Salina, OK, USA)
			TA.U38A (Gravette, AR, USA)
			TA.U39A (Green Forest, AR, USA)
			TA.U40A (Yellville, AR, USA)
			TA.V32A (Arapaho, OK, USA)
			TA.V33A (Lossen Ranch, Watonga, OK, USA)
			TA.V34A (Guthrie, OK, USA)
			TA.V35A (Meyer Ranch, Chandler, OK, USA)
			TA.V36A (Jenks, OK, USA)
			TA.V37A (Hulbert, OK, USA)
			TA.V38A (Canehill, AR, USA)
			TA.V39A (Pettigrew, AR, USA)
			TA.V40A (Witts Springs, AR, USA)
			TA.W18A (Petrified Forest, AZ, USA)
			TA.W32A (Sentinel, OK, USA)
			TA.W33A (Caddo, Fort Cobb, OK, USA)
			TA.W34A (Bridge Creek, Tuttle, OK, USA)
			TA.W35A (Tecumseh, OK, USA)
			TA.W36A (Wetumka, OK, USA)
			TA.W37B (Quinton, OK, USA)
			TA.W38A (Poteau, OK, USA)
			TA.W39A (Magazine, AR, USA)
			TA.W40A (Ferguson Farm, Pottsville, AR, USA)
			TA.WHTX (Lake Whitney, Meridian, TX, USA)
			TA.X32A (Elmer, OK, USA)
			TA.X33A (Lawton, OK, USA)
			TA.X34A (Smith Ranch, Marlow, OK, USA)
			TA.X35A (Drake, OK, USA)
			TA.X36A (Centrahoma, OK, USA)
			TA.X37A (Clayton, OK, USA)
			TA.X38A (Whitesboro, OK, USA)
			TA.X39A (Fountain Ranch, Mena, AR, USA)
			TA.X40A (Basin Creek Farm, Marlvern, AR, USA)
			TA.Y12C (Blythe, CA, USA)
			TA.Y22D (IRIS PASSCAL Instrument Center, Socorro, NM, USA)
			TA.Y33A (Hilltop Ranch, Iowa Park, TX, USA)
			TA.Y34A (Reagan Ranch, Oscar, OK, USA)
			TA.Y35A (Marietta, OK, USA)
			TA.Y36A (Durant, OK, USA)
			TA.Y37A (Hugo, OK, USA)
			TA.Y38A (Idabel, OK, USA)
			TA.Y39A (Lockesburg, AR, USA)
			TA.Y40A (Okolona, AR, USA)
			TA.Z33A (Whitaker Ranch, Olney, TX, USA)
			TA.Z34A (Collier Ranch, Chico, TX, USA)
			TA.Z35A (Perchaven, Sanger, TX, USA)
			TA.Z36A (Blue Ridge, TX, USA)
			TA.Z37A (Pogue Cattle Company, Sulphur Springs, TX, USA)
			TA.Z38A (Mt. Pleasant, TX, USA)
			TA.Z39A (Irene McRaven, Queen City, TX, USA)
			TA.Z40A (Long Farm, Magnolia, AR, USA)
			TA.Z41A (Richland Creek Farm, El Dorado, AR, USA)
		Channels (0):

  • station metadata is bundled in an Inventory object, which is a collection (~list) of Network objects, ...
  • the nested ObsPy Inventory class structure (Inventory/Network/Station/Channel/Response/...) is closely modelled after FDSN StationXML (the international standard exchange format for station metadata)
  • Network objects are again collections of Station objects, which are collections of Channel objects

In [7]:
# let's request full detail metadata for one particular station
inventory = client.get_stations(network="TA", station="S36A", level="response")

# when searching for many available stations response information is not included by default,
# because of the huge size. we explicitly need to specify that we want response information included
print(inventory)
Inventory created at 2015-08-03T17:13:58.000000Z
	Created by: IRIS WEB SERVICE: fdsnws-station | version: 1.1.16
		    http://service.iris.edu/fdsnws/station/1/query?station=S36A&network...
	Sending institution: IRIS-DMC (IRIS-DMC)
	Contains:
		Networks (1):
			TA
		Stations (1):
			TA.S36A (Lake Cedric, Chanute, KS, USA)
		Channels (49):
			TA.S36A..ACE, TA.S36A..BHE, TA.S36A..BHE, TA.S36A..BHN,
			TA.S36A..BHN, TA.S36A..BHZ, TA.S36A..BHZ, TA.S36A..LCE,
			TA.S36A..LCQ, TA.S36A..LHE, TA.S36A..LHE, TA.S36A..LHN,
			TA.S36A..LHN, TA.S36A..LHZ, TA.S36A..LHZ, TA.S36A..LOG,
			TA.S36A..OCF, TA.S36A..UHE, TA.S36A..UHE, TA.S36A..UHN,
			TA.S36A..UHN, TA.S36A..UHZ, TA.S36A..UHZ, TA.S36A..VCO,
			TA.S36A..VEA, TA.S36A..VEC, TA.S36A..VEP, TA.S36A..VHE,
			TA.S36A..VHE, TA.S36A..VHN, TA.S36A..VHN, TA.S36A..VHZ,
			TA.S36A..VHZ, TA.S36A..VKI, TA.S36A..VM0, TA.S36A..VM1,
			TA.S36A..VM2, TA.S36A..VM3, TA.S36A..VM4, TA.S36A..VM5,
			TA.S36A..VM6, TA.S36A..VPB, TA.S36A.EP.LCE, TA.S36A.EP.LCO,
			TA.S36A.EP.LDM, TA.S36A.EP.LEP, TA.S36A.EP.LIM, TA.S36A.EP.LKM,
			TA.S36A.EP.QEP
In [8]:
network = inventory[0]
print(network)
Network TA (USArray Transportable Array (NSF EarthScope Project))
	Station Count: 1/1721 (Selected/Total)
	2003-01-01T00:00:00.000000Z - 2500-12-31T23:59:59.000000Z
	Access: open
	Contains:
		Stations (1):
			TA.S36A (Lake Cedric, Chanute, KS, USA)
		Channels (49):
			TA.S36A..ACE, TA.S36A..BHE, TA.S36A..BHE, TA.S36A..BHN,
			TA.S36A..BHN, TA.S36A..BHZ, TA.S36A..BHZ, TA.S36A..LCE,
			TA.S36A..LCQ, TA.S36A..LHE, TA.S36A..LHE, TA.S36A..LHN,
			TA.S36A..LHN, TA.S36A..LHZ, TA.S36A..LHZ, TA.S36A..LOG,
			TA.S36A..OCF, TA.S36A..UHE, TA.S36A..UHE, TA.S36A..UHN,
			TA.S36A..UHN, TA.S36A..UHZ, TA.S36A..UHZ, TA.S36A..VCO,
			TA.S36A..VEA, TA.S36A..VEC, TA.S36A..VEP, TA.S36A..VHE,
			TA.S36A..VHE, TA.S36A..VHN, TA.S36A..VHN, TA.S36A..VHZ,
			TA.S36A..VHZ, TA.S36A..VKI, TA.S36A..VM0, TA.S36A..VM1,
			TA.S36A..VM2, TA.S36A..VM3, TA.S36A..VM4, TA.S36A..VM5,
			TA.S36A..VM6, TA.S36A..VPB, TA.S36A.EP.LCE, TA.S36A.EP.LCO,
			TA.S36A.EP.LDM, TA.S36A.EP.LEP, TA.S36A.EP.LIM, TA.S36A.EP.LKM,
			TA.S36A.EP.QEP
In [9]:
station = network[0]
print(station)
Station S36A (Lake Cedric, Chanute, KS, USA)
	Station Code: S36A
	Channel Count: 49/49 (Selected/Total)
	2010-03-16T00:00:00.000000Z - 2012-03-02T23:59:59.000000Z
	Access: open 
	Latitude: 37.72, Longitude: -95.59, Elevation: 299.0 m
	Available Channels:
		S36A..ACE, S36A..BHE, S36A..BHE, S36A..BHN, S36A..BHN, S36A..BHZ,
		S36A..BHZ, S36A..LCE, S36A..LCQ, S36A..LHE, S36A..LHE, S36A..LHN,
		S36A..LHN, S36A..LHZ, S36A..LHZ, S36A..LOG, S36A..OCF, S36A..UHE,
		S36A..UHE, S36A..UHN, S36A..UHN, S36A..UHZ, S36A..UHZ, S36A..VCO,
		S36A..VEA, S36A..VEC, S36A..VEP, S36A..VHE, S36A..VHE, S36A..VHN,
		S36A..VHN, S36A..VHZ, S36A..VHZ, S36A..VKI, S36A..VM0, S36A..VM1,
		S36A..VM2, S36A..VM3, S36A..VM4, S36A..VM5, S36A..VM6, S36A..VPB,
		S36A.EP.LCE, S36A.EP.LCO, S36A.EP.LDM, S36A.EP.LEP, S36A.EP.LIM,
		S36A.EP.LKM, S36A.EP.QEP
In [10]:
station = station.select(channel="BH*")
print(station)
Station S36A (Lake Cedric, Chanute, KS, USA)
	Station Code: S36A
	Channel Count: 49/49 (Selected/Total)
	2010-03-16T00:00:00.000000Z - 2012-03-02T23:59:59.000000Z
	Access: open 
	Latitude: 37.72, Longitude: -95.59, Elevation: 299.0 m
	Available Channels:
		S36A..BHE, S36A..BHE, S36A..BHN, S36A..BHN, S36A..BHZ, S36A..BHZ
In [11]:
channel = station[0]
print(channel)
print(channel.response)
Channel 'BHE', Location '' 
	Time range: 2010-03-16T00:00:00.000000Z - 2011-09-10T15:59:59.000000Z
	Latitude: 37.72, Longitude: -95.59, Elevation: 299.0 m, Local Depth: 0.0 m
	Azimuth: 90.00 degrees from north, clockwise
	Dip: 0.00 degrees down from horizontal
	Channel types: GEOPHYSICAL
	Sampling Rate: 40.00 Hz
	Sensor: None
	Response information available
Channel Response
	From M/S (velocity in meters per second) to COUNTS (digital counts)
	Overall Sensitivity: 6.27192e+08 defined at 0.200 Hz
	3 stages:
		Stage 1: PolesZerosResponseStage from M/S to V, gain: 1495.34
		Stage 2: CoefficientsTypeResponseStage from V to COUNTS, gain: 419430
		Stage 3: CoefficientsTypeResponseStage from COUNTS to COUNTS, gain: 1
In [ ]:
# you can use Tab-Completion to see what attributes/methods the inventory object has:
inventory.
channel.
  • local files can be read using the read_inventory() function.
  • filetype is autodetected (but many real-world StationXML files do not adhere to the official schema, explicitly specify format="STATIONXML" in that case!)
In [12]:
from obspy import read_inventory

inventory2 = read_inventory("./data/station_uh1.xml", format="STATIONXML")
print(inventory2)
Inventory created at 2015-07-22T11:43:52.490000Z
	Created by: fdsn-stationxml-converter/1.0.8
		    http://www.iris.edu/fdsnstationconverter
	Sending institution: GOF
	Contains:
		Networks (1):
			BW
		Stations (2):
			BW.UH1 (Unterhaching Uni, BW-Net)
			BW.UH1 (Unterhaching Uni, BW-Net)
		Channels (6):
			BW.UH1..EHE, BW.UH1..EHE, BW.UH1..EHN, BW.UH1..EHN, BW.UH1..EHZ,
			BW.UH1..EHZ

3. Waveform Data (seismometer time series)

  • again, several different protocols are implemented in ObsPy to connect to all important seismological data centers
  • also, local files in all important exchange formats can be read
  • the most important protocol are FDSN web services (other protocols work similar)
  • real time data can be accessed using obspy.seedlink
  • the "get_waveforms()" method needs the unique identification of the station (network, station, location and channel codes) and a time range (start time, end time) of requested data
In [13]:
stream = client.get_waveforms(network="TA", station="S36A",
                              location="*", channel="BH*",
                              starttime=t+10*60, endtime=t+70*60)

# for functions/methods that need a fixed set of parameters,
# we usually omit the parameter names and specify them in the expected order
# Note that new timestamp objects can be created by
# adding/subtracting seconds to/from an existing timestamp object.
# (for details search the ObsPy documentation pages for "UTCDateTime")
stream = client.get_waveforms("TA", "S36A", "*", "BH*", t+10*60, t+70*60)

print(stream)
stream.plot()
3 Trace(s) in Stream:
TA.S36A..BHE | 2011-03-11T05:56:23.200000Z - 2011-03-11T06:56:23.200000Z | 40.0 Hz, 144001 samples
TA.S36A..BHN | 2011-03-11T05:56:23.200000Z - 2011-03-11T06:56:23.200000Z | 40.0 Hz, 144001 samples
TA.S36A..BHZ | 2011-03-11T05:56:23.200000Z - 2011-03-11T06:56:23.200000Z | 40.0 Hz, 144001 samples

the nested ObsPy Inventory class structure (Inventory/Station/Channel/Response/...) is closely modelled after FDSN StationXML (the international standard exchange format for station metadata)

  • waveform data is bundled in a Stream object, which is a collection (~list) of Trace objects
  • Trace objects consist of one single, contiguous waveform data block (i.e. regularly spaced time series, no gaps)
  • Trace objects consist of two attributes:
    • trace.data (the raw time series as an numpy.ndarray) and..
    • trace.stats (metainformation needed to interpret the raw sample data)

In [14]:
trace = stream[0]
# trace.data is the numpy array with the raw samples
print(trace.data)
print(trace.data[20:30])
# arithmetic operations on the data
print(trace.data[20:30] / 223.5)
# using attached numpy methods
print(trace.data.mean())
# pointers to the array in memory can be passed to C/Fortran routines from inside Python!
[  -377   -371   -399 ..., -69980 -69789 -69569]
[-452 -479 -486 -472 -442 -438 -459 -451 -456 -475]
[-2.02237136 -2.14317673 -2.17449664 -2.11185682 -1.97762864 -1.95973154
 -2.05369128 -2.01789709 -2.04026846 -2.12527964]
-481.474371706
In [15]:
# trace.stats contains the basic metadata identifying the trace
print(trace)
print(trace.stats)
print(trace.stats.sampling_rate)
TA.S36A..BHE | 2011-03-11T05:56:23.200000Z - 2011-03-11T06:56:23.200000Z | 40.0 Hz, 144001 samples
         network: TA
         station: S36A
        location: 
         channel: BHE
       starttime: 2011-03-11T05:56:23.200000Z
         endtime: 2011-03-11T06:56:23.200000Z
   sampling_rate: 40.0
           delta: 0.025
            npts: 144001
           calib: 1.0
         _format: MSEED
           mseed: AttribDict({'record_length': 4096, 'encoding': u'STEIM2', 'filesize': 704512, u'dataquality': u'M', 'number_of_records': 172, 'byteorder': u'>'})
40.0
In [ ]:
# many convenience routines are attahed to Stream/Trace, use Tab completion
stream.
  • local files can be read using the read() function.
  • filetype is autodetected (but can be manually specified to skip autodetection for speed)
In [16]:
from obspy import read

stream2 = read("./data/waveforms_uh1_eh?.mseed")
print(stream2)
3 Trace(s) in Stream:
BW.UH1..EHE | 2010-05-27T16:24:31.799999Z - 2010-05-27T16:24:51.799999Z | 200.0 Hz, 4001 samples
BW.UH1..EHN | 2010-05-27T16:24:31.799999Z - 2010-05-27T16:24:51.799999Z | 200.0 Hz, 4001 samples
BW.UH1..EHZ | 2010-05-27T16:24:31.799999Z - 2010-05-27T16:24:51.799999Z | 200.0 Hz, 4001 samples
  • timestamps are handled by UTCDateTime class throughout ObsPy
In [17]:
from obspy import UTCDateTime

t1 = UTCDateTime("2015-08-04T10:30")
print(t1.hour)
print(t1.strftime("%c"))
10
Tue Aug  4 10:30:00 2015
  • +/- operator to add/subtract seconds
  • - operator to get diff of two timestamps in seconds
In [18]:
# calculate time since Tohoku earthquake in years
now = UTCDateTime()
print((now - t) / (3600 * 24 * 365))

# 2 hours from now
print(now + 2 * 3600)
4.40130931615
2015-08-03T19:14:33.794217Z

4. Converting raw seismometer recordings to physical units (aka instrument correction)

  • for this we need to combine the raw waveform data of the recording system (seismometer, digitizer) with the metadata on its amplitude and phase response (the instrument response)
  • these information are kept separate for various practical and technical reasons (space in storage and streaming, correcting of errors made in the metadata, ...)
In [19]:
# first, let's have a look at this channel's instrument response
channel.plot(min_freq=1e-4);
/home/megies/anaconda/lib/python2.7/site-packages/matplotlib/axes/_axes.py:475: UserWarning: No labelled objects found. Use label='...' kwarg on individual plots.
  warnings.warn("No labelled objects found. "
In [20]:
# we already have fetched the station metadata,
# including every piece of information down to the instrument response

# let's make on a copy of the raw data, to be able to compare afterwards
stream_corrected = stream.copy()

# attach the instrument response to the waveforms..
stream_corrected.attach_response(inventory)

# and convert the data to ground velocity in m/s,
# taking into account the specifics of the recording system
stream_corrected.remove_response(water_level=10, output="VEL")

stream[0].plot()
stream_corrected[0].plot()

ObsPy has much more functionality, check it out on the ObsPy documentation pages at https://docs.obspy.org.

  • many, many convenience routines attached to Stream/Trace, Catalog/Event/.., Inventory/... for easy manipulation
  • filtering, detrending, demeaning, rotating, resampling, ...
  • array analysis, cross correlation routines, event detection, ...
  • estimate travel times and plot ray paths of seismic phases for specified source/receiver combinations
  • command line utilities (obspy-print, obspy-plot, obspy-scan, ...)
  • ...


Automated Data Fetching/Processing Example

This example prepares instrument corrected waveforms, 30 seconds around expected P arrival (buffer for processing!) for an epicentral range of 30-40 degrees for any TA station/earthquake combination with magnitude larger 7.

In [21]:
from obspy.taup import TauPyModel
from obspy.core.util.geodetics import gps2DistAzimuth, kilometer2degrees

model = TauPyModel(model="iasp91")

catalog = client.get_events(starttime="2009-001", endtime="2012-001", minmagnitude=7)
print(catalog)

network = "TA"
minradius = 30
maxradius = 40
phase = "P"

for event in catalog:
    origin = event.origins[0]
    
    try:
        inventory = client.get_stations(network=network,
                                        startbefore=origin.time, endafter=origin.time,
                                        longitude=origin.longitude, latitude=origin.latitude,
                                        minradius=minradius, maxradius=maxradius)
    except:
        continue

    print(event)

    for station in inventory[0][:3]:
        distance, _, _ = gps2DistAzimuth(origin.latitude, origin.longitude,
                                         station.latitude, station.longitude)
        distance = kilometer2degrees(distance / 1e3)
        arrivals = model.get_travel_times(origin.depth / 1e3, distance,
                                          phase_list=[phase])
        traveltime = arrivals[0].time
        arrival_time = origin.time + traveltime
        
        st = client.get_waveforms(network, station.code, "*", "BH*",
                                  arrival_time - 200, arrival_time + 200,
                                  attach_response=True)
        st.remove_response(water_level=10, output="VEL")
        st.filter("lowpass", freq=1)
        st.trim(arrival_time - 10, arrival_time + 20)
        st.plot()
    break
59 Event(s) in Catalog:
2011-12-14T05:04:57.810000Z |  -7.528, +146.814 | 7.1 MW
2011-10-28T18:54:34.750000Z | -14.557,  -76.121 | 7.0 MW
...
2009-01-03T22:33:42.660000Z |  -0.709, +133.312 | 7.2 MW
2009-01-03T19:43:55.840000Z |  -0.527, +132.602 | 7.4 MW
To see all events call 'print(CatalogObject.__str__(print_all=True))'
Event:	2011-06-24T03:09:38.920000Z | +51.980, -171.820 | 7.3 MW

	        resource_id: ResourceIdentifier(id="smi:service.iris.edu/fdsnws/event/1/query?eventid=3316471")
	         event_type: u'earthquake'
	---------
	 event_descriptions: 1 Elements
	            origins: 1 Elements
	         magnitudes: 1 Elements

Exercise

Problems? Questions?

  • ObsPy Documentation (use the search)
  • Use IPython tab completion
  • Use interactive IPython help (e.g. after import type: readEvents?)
  • Ask!

a) Read the event metadata from local file "./data/events_unterhaching.xml". Print the catalog summary.

In [22]:
from obspy import readEvents
catalog = readEvents("./data/events_unterhaching.xml")
print(catalog)
/home/megies/anaconda/lib/python2.7/site-packages/obspy-0.10.2-py2.7-linux-x86_64.egg/obspy/core/event.pyc:447: UserWarning: The resource identifier 'smi:de.erdbeben-in-bayern/origin/6429bfd9-8a51-4bef-ba74-193c809f90f7' already exists and points to another object: 'Origin(resource_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/origin/6429bfd9-8a51-4bef-ba74-193c809f90f7"), time=UTCDateTime(2010, 5, 27, 16, 24, 31, 802036), longitude=11.6457, latitude=48.0456, depth=4640.576 [uncertainty=360.124613583], depth_type=u'from location', method_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/location_method/NLLoc/1"), earth_model_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/earth_model/UH/1"), quality=OriginQuality(associated_phase_count=8, used_phase_count=8, associated_station_count=4, used_station_count=4, depth_phase_count=0, standard_error=0.028597, azimuthal_gap=134.0, minimum_distance=0.0155129519113, maximum_distance=0.0750076373802, median_distance=0.0318781782186), origin_uncertainty=OriginUncertainty(min_horizontal_uncertainty=265.791274229, max_horizontal_uncertainty=293.646266911, azimuth_max_horizontal_uncertainty=0.0, preferred_description=u'uncertainty ellipse'))'.It will now point to the object referred to by the new resource identifier.
  identifiers with a user-set, fixed id.
/home/megies/anaconda/lib/python2.7/site-packages/obspy-0.10.2-py2.7-linux-x86_64.egg/obspy/core/event.pyc:447: UserWarning: The resource identifier 'smi:de.erdbeben-in-bayern/origin/806631f7-7dff-43e8-9c39-bd26bb6d791d' already exists and points to another object: 'Origin(resource_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/origin/806631f7-7dff-43e8-9c39-bd26bb6d791d"), time=UTCDateTime(2010, 5, 27, 16, 43, 49, 542034), longitude=11.6468, latitude=48.0468, depth=4595.166 [uncertainty=311.057732242], depth_type=u'from location', method_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/location_method/NLLoc/1"), earth_model_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/earth_model/UH/1"), quality=OriginQuality(associated_phase_count=8, used_phase_count=8, associated_station_count=4, used_station_count=4, depth_phase_count=0, standard_error=0.023413, azimuthal_gap=133.0, minimum_distance=0.0168779974339, maximum_distance=0.0759521787677, median_distance=0.0307677813768), origin_uncertainty=OriginUncertainty(min_horizontal_uncertainty=287.989967859, max_horizontal_uncertainty=388.027951811, azimuth_max_horizontal_uncertainty=90.0, preferred_description=u'uncertainty ellipse'))'.It will now point to the object referred to by the new resource identifier.
  identifiers with a user-set, fixed id.
/home/megies/anaconda/lib/python2.7/site-packages/obspy-0.10.2-py2.7-linux-x86_64.egg/obspy/core/event.pyc:447: UserWarning: The resource identifier 'smi:de.erdbeben-in-bayern/origin/d3e87c92-0757-40b2-b505-0e2089bd931c' already exists and points to another object: 'Origin(resource_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/origin/d3e87c92-0757-40b2-b505-0e2089bd931c"), time=UTCDateTime(2013, 4, 16, 21, 51, 42, 648944), longitude=11.6428207958, latitude=48.0462984512, depth=4826.758 [uncertainty=464.175411974], depth_type=u'from location', method_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/location_method/NLLoc/1"), earth_model_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/earth_model/UH/1"), quality=OriginQuality(associated_phase_count=6, used_phase_count=6, associated_station_count=3, used_station_count=3, depth_phase_count=0, standard_error=0.005118, azimuthal_gap=162.0, minimum_distance=0.0157403608531, maximum_distance=0.0354812874494, median_distance=0.0289325118359), origin_uncertainty=OriginUncertainty(min_horizontal_uncertainty=437.207276706, max_horizontal_uncertainty=565.099991871, azimuth_max_horizontal_uncertainty=90.0, preferred_description=u'uncertainty ellipse'))'.It will now point to the object referred to by the new resource identifier.
  identifiers with a user-set, fixed id.
/home/megies/anaconda/lib/python2.7/site-packages/obspy-0.10.2-py2.7-linux-x86_64.egg/obspy/core/event.pyc:447: UserWarning: The resource identifier 'smi:de.erdbeben-in-bayern/origin/8b43362c-c8f7-49db-b59f-67cc07ec2076' already exists and points to another object: 'Origin(resource_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/origin/8b43362c-c8f7-49db-b59f-67cc07ec2076"), time=UTCDateTime(2013, 4, 16, 21, 51, 47, 556942), longitude=11.6432803163, latitude=48.0453444962, depth=4831.299 [uncertainty=461.54137953], depth_type=u'from location', method_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/location_method/NLLoc/1"), earth_model_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/earth_model/UH/1"), quality=OriginQuality(associated_phase_count=6, used_phase_count=6, associated_station_count=3, used_station_count=3, depth_phase_count=0, standard_error=0.003604, azimuthal_gap=160.0, minimum_distance=0.0148602424216, maximum_distance=0.0364670927192, median_distance=0.0290581161824), origin_uncertainty=OriginUncertainty(min_horizontal_uncertainty=404.316705719, max_horizontal_uncertainty=503.427831412, azimuth_max_horizontal_uncertainty=90.0, preferred_description=u'uncertainty ellipse'))'.It will now point to the object referred to by the new resource identifier.
  identifiers with a user-set, fixed id.
/home/megies/anaconda/lib/python2.7/site-packages/obspy-0.10.2-py2.7-linux-x86_64.egg/obspy/core/event.pyc:447: UserWarning: The resource identifier 'smi:de.erdbeben-in-bayern/origin/b09e629d-33da-4181-a4d4-d223e81b3550' already exists and points to another object: 'Origin(resource_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/origin/b09e629d-33da-4181-a4d4-d223e81b3550"), time=UTCDateTime(2013, 4, 16, 22, 0, 1, 861996), longitude=11.6434004448, latitude=48.0466875761, depth=4794.971 [uncertainty=481.564882696], depth_type=u'from location', method_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/location_method/NLLoc/1"), earth_model_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/earth_model/UH/1"), quality=OriginQuality(associated_phase_count=6, used_phase_count=6, associated_station_count=3, used_station_count=3, depth_phase_count=0, standard_error=0.004702, azimuthal_gap=161.0, minimum_distance=0.0161931373738, maximum_distance=0.0351474020503, median_distance=0.0284194623878), origin_uncertainty=OriginUncertainty(min_horizontal_uncertainty=394.799585562, max_horizontal_uncertainty=540.778869035, azimuth_max_horizontal_uncertainty=90.0, preferred_description=u'uncertainty ellipse'))'.It will now point to the object referred to by the new resource identifier.
  identifiers with a user-set, fixed id.
7 Event(s) in Catalog:
2010-05-27T16:24:31.802036Z | +48.048,  +11.646 | 2.08662460284 Ml
2010-05-27T16:43:49.542034Z | +48.048,  +11.646 | 1.4954033383 Ml
2013-04-16T21:51:42.648944Z | +48.046,  +11.643 | 1.96765657554 Ml
2013-04-16T21:51:47.556942Z | +48.045,  +11.643 | 1.88540591771 Ml
2013-04-16T22:00:01.861996Z | +48.047,  +11.643 | 1.31056358704 Ml
2013-04-16T22:15:28.557771Z | +48.046,  +11.643 | 1.76859128731 Ml
2013-04-18T18:15:57.733615Z | +48.045,  +11.642 | 1.57623047808 Ml
/home/megies/anaconda/lib/python2.7/site-packages/obspy-0.10.2-py2.7-linux-x86_64.egg/obspy/core/event.pyc:447: UserWarning: The resource identifier 'smi:de.erdbeben-in-bayern/origin/ede0052f-ee08-4a0d-890d-e41e16efd4a0' already exists and points to another object: 'Origin(resource_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/origin/ede0052f-ee08-4a0d-890d-e41e16efd4a0"), time=UTCDateTime(2013, 4, 16, 22, 15, 28, 557771), longitude=11.6432108031, latitude=48.0460414498, depth=4854.004 [uncertainty=459.062121548], depth_type=u'from location', method_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/location_method/NLLoc/1"), earth_model_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/earth_model/UH/1"), quality=OriginQuality(associated_phase_count=6, used_phase_count=6, associated_station_count=3, used_station_count=3, depth_phase_count=0, standard_error=0.004285, azimuthal_gap=161.0, minimum_distance=0.0155346378827, maximum_distance=0.0357701416438, median_distance=0.0288008465412), origin_uncertainty=OriginUncertainty(min_horizontal_uncertainty=428.059959736, max_horizontal_uncertainty=568.761862395, azimuth_max_horizontal_uncertainty=90.0, preferred_description=u'uncertainty ellipse'))'.It will now point to the object referred to by the new resource identifier.
  identifiers with a user-set, fixed id.
/home/megies/anaconda/lib/python2.7/site-packages/obspy-0.10.2-py2.7-linux-x86_64.egg/obspy/core/event.pyc:447: UserWarning: The resource identifier 'smi:de.erdbeben-in-bayern/origin/afb5892c-9fde-4d68-a2fd-c180a47d4107' already exists and points to another object: 'Origin(resource_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/origin/afb5892c-9fde-4d68-a2fd-c180a47d4107"), time=UTCDateTime(2013, 4, 18, 18, 15, 57, 733615), longitude=11.641856886, latitude=48.0453400679, depth=4749.561 [uncertainty=402.396909058], depth_type=u'from location', method_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/location_method/NLLoc/1"), earth_model_id=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/earth_model/UH/1"), quality=OriginQuality(associated_phase_count=6, used_phase_count=6, associated_station_count=3, used_station_count=3, depth_phase_count=0, standard_error=0.006218, azimuthal_gap=165.0, minimum_distance=0.0146934784333, maximum_distance=0.0363577493532, median_distance=0.0299202286402), origin_uncertainty=OriginUncertainty(min_horizontal_uncertainty=421.99247666, max_horizontal_uncertainty=471.864283817, azimuth_max_horizontal_uncertainty=90.0, preferred_description=u'uncertainty ellipse'))'.It will now point to the object referred to by the new resource identifier.
  identifiers with a user-set, fixed id.

b) Take one event out of the catalog. Print its summary. You can see, there is information included on picks set for the event. Print the information of at least one pick that is included in the event metadata. We now know one station that recorded the event.

In [23]:
event = catalog[0]
print(event)
print(event.picks[0])
Event:	2010-05-27T16:24:31.802036Z | +48.048,  +11.646 | 2.08662460284 Ml

	        resource_id: ResourceIdentifier(id="smi:de.erdbeben-in-bayern/event/20100622214704")
	      creation_info: CreationInfo(agency_id='Erdbebendienst Bayern', agency_uri=ResourceIdentifier(id="smi:de.erdbeben-in-bayern/agency"), author='megies', creation_time=UTCDateTime(2014, 9, 19, 14, 58, 18, 281839))
	---------
	              picks: 22 Elements
	            origins: 3 Elements
	         magnitudes: 1 Elements
	 station_magnitudes: 4 Elements
Pick
	 resource_id: ResourceIdentifier(id="smi:de.erdbeben-in-bayern/pick/1341b3dd-21de-4c6c-92db-40bfe76e8950")
	        time: UTCDateTime(2010, 5, 27, 16, 24, 33, 315000) [uncertainty=0.01]
	 waveform_id: WaveformStreamID(network_code='BW', station_code='UH1', channel_code='EHZ', location_code='')
	  phase_hint: 'P'
	    polarity: u'negative'

c) Save the origin time of the event in a new variable. Download waveform data for the station around the time of the event (e.g. 10 seconds before and 20 seconds after), connecting to the FDSN server at the observatory at "http://erde.geophysik.uni-muenchen.de" (or read from local file ./data/waveforms_uh1_eh.mseed). Put a "*" wildcard as the third (and last) letter of the channel code to download all three components (vertical, north, east). Plot the waveform data.

In [24]:
t = event.origins[0].time

client_lmu = Client("http://erde.geophysik.uni-muenchen.de")

stream = client_lmu.get_waveforms(network="BW", station="UH1", location="", channel="EH*",
                                  starttime=t-10, endtime=t+20)
stream.plot()