#!/usr/bin/env python # coding: utf-8 #
#
#
#
ObsPy Tutorial
#
Handling Station Metadata
#
#
#
# image: User:Abbaszade656 / Wikimedia Commons / CC-BY-SA-4.0 # ## Workshop for the "Training in Network Management Systems and Analytical Tools for Seismic" # ### Baku, October 2018 # # Seismo-Live: http://seismo-live.org # # ##### Authors: # * Lion Krischer ([@krischer](https://github.com/krischer)) # * Tobias Megies ([@megies](https://github.com/megies)) # --- # ![](images/obspy_logo_full_524x179px.png) # In[1]: get_ipython().run_line_magic('matplotlib', 'inline') from __future__ import print_function import matplotlib.pyplot as plt plt.style.use('ggplot') plt.rcParams['figure.figsize'] = 12, 8 # - for station metadata, the de-facto standard of the future (replacing SEED/RESP) is [FDSN StationXML](http://www.fdsn.org/xml/station/) # - FDSN StationXML files can be read using **`read_inventory()`** # In[2]: import obspy inventory = obspy.read_inventory("./data/station_PFO.xml") print(type(inventory)) # - the nested ObsPy Inventory class structure (Inventory/Station/Channel/Response/...) is closely modelled after FDSN StationXML # # In[3]: get_ipython().system('head data/station_BFO.xml') # In[4]: print(inventory) # In[5]: network = inventory[0] print(network) # In[6]: station = network[0] print(station) # In[7]: channel = station[0] print(channel) # In[8]: print(channel.response) # In[9]: st = obspy.read("./data/waveform_PFO.mseed") print(st) # In[10]: inv = obspy.read_inventory("./data/station_PFO.xml", format="STATIONXML") # In[11]: print(st[0].stats) # - the instrument response can be deconvolved from the waveform data using the convenience method **`Stream.remove_response()`** # - evalresp is used internally to calculate the instrument response # In[12]: st.plot() st.remove_response(inventory=inv) st.plot() # - several options can be used to specify details of the deconvolution (water level, frequency domain prefiltering), output units (velocity/displacement/acceleration), demeaning, tapering and to specify if any response stages should be omitted # In[13]: st = obspy.read("./data/waveform_PFO.mseed") st.remove_response(inventory=inv, water_level=60, pre_filt=(0.01, 0.02, 8, 10), output="DISP") st.plot() # Finally, if station metadata is not available from the operator or from the data center serving the data, or in case of temporary station deployments and field campaigns, full station metadata can be assembled using ObsPy, including response information gathered from the [IRIS Nominal Response Library (NRL)](http://ds.iris.edu/NRL/): # # In[14]: import obspy from obspy.core.inventory import Inventory, Network, Station, Channel, Site from obspy.clients.nrl.client import NRL # We'll first create all the various objects. These strongly follow the # hierarchy of StationXML files. inv = Inventory( # We'll add networks later. networks=[], # The source should be the id whoever create the file. source="ObsPy-Tutorial") net = Network( # This is the network code according to the SEED standard. code="XX", # A list of stations. We'll add one later. stations=[], description="A test stations.", # Start-and end dates are optional. start_date=obspy.UTCDateTime(2016, 1, 2)) sta = Station( # This is the station code according to the SEED standard. code="ABC", latitude=1.0, longitude=2.0, elevation=345.0, creation_date=obspy.UTCDateTime(2016, 1, 2), site=Site(name="First station")) cha = Channel( # This is the channel code according to the SEED standard. code="HHZ", # This is the location code according to the SEED standard. location_code="", # Note that these coordinates can differ from the station coordinates. latitude=1.0, longitude=2.0, elevation=345.0, depth=10.0, azimuth=0.0, dip=-90.0, sample_rate=200) # By default this accesses the always up-to-date NRL online. # Offline copies of the NRL can also be used instead. nrl = NRL() # The contents of the NRL can be explored interactively in a Python prompt, # see API documentation of NRL submodule: # http://docs.obspy.org/packages/obspy.clients.nrl.html # Here we assume that the end point of data logger and sensor are already # known: response = nrl.get_response( # doctest: +SKIP sensor_keys=['Nanometrics', 'Trillium Compact', '120 s'], datalogger_keys=['REF TEK', 'RT 130 & 130-SMA', '1', '200']) # Now tie it all together. cha.response = response sta.channels.append(cha) net.stations.append(sta) inv.networks.append(net) # And finally write it to a StationXML file. We also force a validation against # the StationXML schema to ensure it produces a valid StationXML file. # # Note that it is also possible to serialize to any of the other inventory # output formats ObsPy supports. print(inv) print(inv[0][0][0]) inv.write("station.xml", format="stationxml", validate=True) # In[15]: cha = inv[0][0][0] cha.plot(min_freq=0.001) print(cha) # The contents of the NRL can be inspected in an interactive shell: # In[16]: nrl.sensors # In[17]: nrl.sensors['Streckeisen'] # In[18]: nrl.dataloggers