{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "
\n", "
\n", "
ObsPy Tutorial
\n", "
Handling Event Metadata
\n", "
\n", "
\n", "
\n", "image: User:Abbaszade656 / Wikimedia Commons / CC-BY-SA-4.0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Workshop for the \"Training in Network Management Systems and Analytical Tools for Seismic\"\n", "### Baku, October 2018\n", "\n", "Seismo-Live: http://seismo-live.org\n", "\n", "##### Authors:\n", "* Lion Krischer ([@krischer](https://github.com/krischer))\n", "* Tobias Megies ([@megies](https://github.com/megies))\n", "---" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "![](images/obspy_logo_full_524x179px.png)" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "%matplotlib inline\n", "from __future__ import print_function\n", "import matplotlib.pyplot as plt\n", "plt.style.use('ggplot')\n", "plt.rcParams['figure.figsize'] = 12, 8" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- for event metadata, the de-facto standard is [QuakeML (an xml document structure)](https://quake.ethz.ch/quakeml/)\n", "- QuakeML files can be read using **`read_events()`**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import obspy\n", "\n", "catalog = obspy.read_events(\"./data/south_napa_with_some_aftershocks.xml\")\n", "print(catalog)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- **`read_events()`** function returns a **`Catalog`** object, which is\n", "a collection of **`Event`** objects." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(type(catalog))\n", "print(type(catalog[0]))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "event = catalog[0]\n", "print(event)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Event objects are again collections of other resources.\n", "- the nested ObsPy Event class structure (Catalog/Event/Origin/Magnitude/FocalMechanism/...) is closely modelled after QuakeML\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(type(event.origins))\n", "print(type(event.origins[0]))\n", "print(event.origins[0])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(type(event.magnitudes))\n", "print(type(event.magnitudes[0]))\n", "print(event.magnitudes[0])" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# try event. to get an idea what \"children\" elements event has" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- The Catalog object contains some convenience methods to make\n", "working with events easier.\n", "- for example, the included events can be filtered with various keys." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "largest_magnitude_events = catalog.filter(\"magnitude >= 4.0\")\n", "print(largest_magnitude_events)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- There is a basic preview plot using the matplotlib basemap module." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "catalog.plot(projection=\"local\", resolution=\"i\", label=\"magnitude\");" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- a (modified) Catalog can be output to file in a number of different formats." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "largest_magnitude_events.write(\"/tmp/large_events.xml\", format=\"QUAKEML\")\n", "!ls -l /tmp/large_events.xml" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- the event type classes can be used to build up Events/Catalogs/Picks/.. from scratch in custom processing work flows and to share them with other researchers in the de facto standard format QuakeML" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from obspy import UTCDateTime\n", "from obspy.core.event import Catalog, Event, Origin, Magnitude\n", "from obspy.geodetics import FlinnEngdahl\n", "\n", "cat = Catalog()\n", "cat.description = \"Just a fictitious toy example catalog built from scratch\"\n", "\n", "e = Event()\n", "e.event_type = \"not existing\"\n", "\n", "o = Origin()\n", "o.time = UTCDateTime(2014, 2, 23, 18, 0, 0)\n", "o.latitude = 47.6\n", "o.longitude = 12.0\n", "o.depth = 10000\n", "o.depth_type = \"operator assigned\"\n", "o.evaluation_mode = \"manual\"\n", "o.evaluation_status = \"preliminary\"\n", "o.region = FlinnEngdahl().get_region(o.longitude, o.latitude)\n", "\n", "m = Magnitude()\n", "m.mag = 7.2\n", "m.magnitude_type = \"Mw\"\n", "\n", "m2 = Magnitude()\n", "m2.mag = 7.4\n", "m2.magnitude_type = \"Ms\"\n", "\n", "# also included could be: custom picks, amplitude measurements, station magnitudes,\n", "# focal mechanisms, moment tensors, ...\n", "\n", "# make associations, put everything together\n", "cat.append(e)\n", "e.origins = [o]\n", "e.magnitudes = [m, m2]\n", "m.origin_id = o.resource_id\n", "m2.origin_id = o.resource_id\n", "\n", "print(cat)\n", "cat.write(\"/tmp/my_custom_events.xml\", format=\"QUAKEML\")\n", "!cat /tmp/my_custom_events.xml" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.2" } }, "nbformat": 4, "nbformat_minor": 1 }