Commit 37a4d8cc authored by Peter Evans's avatar Peter Evans
Browse files

Use type hints

- Also, silence mypy.
parent 60a370be
......@@ -20,24 +20,33 @@ Can run standalone:
import datetime
import os
import sys
from typing import List, Optional, Union
import urllib.request as ul
from xml.etree import ElementTree as ET
import yaml
QUAKEML_NS = {"ns": ""}
QUAKEML_NS: dict = {"ns": ""}
def fetch_fm(root, ns, preferredfmID):
def _perror(msg: str) -> None:
print(msg, file=sys.stderr)
def fetch_fm(root: ET.Element, ns: dict, preferredfmID: str) -> list:
Extract interesting properties from the focal mechanism with
the given publicID.
root: ElementTree root element.
ns (string): string, its namespace.
ns (dict): its namespace.
preferredfmID (string): the focal mechanism to hunt for.
Returns a list of one dictionary filled from each of the
<nodalPlane1> and <nodalPlane2> components of the <nodalPlane>
for fm in root[0][0].findall("ns:focalMechanism", ns):
if fm.attrib["publicID"] != preferredfmID:
......@@ -47,23 +56,33 @@ def fetch_fm(root, ns, preferredfmID):
np = fm.find("ns:nodalPlanes", ns)
# Expect there's only one <nodalPlanes>!
if not np:
_perror("Oops: no <nodalPlanes> object seen")
d = [None, None]
d: List[dict] = []
for k in range(2):
plane = np.find("ns:nodalPlane" + str(k + 1), ns)
d[k] = dict()
if not plane:
for child in plane:
v = child.find("ns:value", ns).text
found = child.find("ns:value", ns)
if not found:
v = found.text
tag = child.tag
tag = tag[tag.index("}") + 1 :]
d[k][tag] = float(v)
d[k][tag] = float(str(v))
except ValueError:
return d
def fetch_magnitude(root, ns, preferredmagnitudeID):
def fetch_magnitude(
root: ET.Element, ns: dict, preferredmagnitudeID: str
) -> Union[float, None]:
for m in root[0][0].findall("ns:magnitude", ns):
if m.attrib["publicID"] != preferredmagnitudeID:
......@@ -71,20 +90,23 @@ def fetch_magnitude(root, ns, preferredmagnitudeID):
child = m.find("ns:mag", ns)
if not child:
return None
v = child.find("ns:value", ns).text
value = child.find("ns:value", ns)
if not value:
return None
v = value.text
mag = float(v)
mag = float(str(v))
except ValueError:
mag = None
return None
return mag
def fetch_origin(root, ns, preferredoriginID):
def fetch_origin(root, ns: dict, preferredoriginID: str) -> dict:
Extract interesting properties from the origin with given publicID.
root: ElementTree root element.
ns (string): the XML object's namespace.
ns (dict): the XML object's namespace.
preferredoriginID (string): the origin to hunt for.
for o in root[0][0].findall("ns:origin", ns):
......@@ -111,7 +133,7 @@ def fetch_origin(root, ns, preferredoriginID):
return d
def fetch_quakeml_ws(evid):
def fetch_quakeml_ws(evid: str) -> str:
Query fdsnws-event web service, and return string
to fetch_quakeml() for parsing.
......@@ -142,7 +164,7 @@ def fetch_quakeml_ws(evid):
return buf
def fetch_quakeml(path):
def fetch_quakeml(path: str) -> Union[dict, None]:
Prepare a dictionary holding the interesting things found by
reading the QuakeML file served for a given event.
......@@ -176,15 +198,32 @@ def fetch_quakeml(path):
# e.g. ""
evid = event.attrib["publicID"].split("/")[-1]
except AttributeError:
_perror("Oops, couldn't get event id from " + event.attrib["publicID"])
preferredoriginID = root[0][0].find("ns:preferredOriginID", ns).text
preferredmagID = root[0][0].find("ns:preferredMagnitudeID", ns).text
preferredoriginIDElem = root[0][0].find("ns:preferredOriginID", ns)
if not preferredoriginIDElem:
return None
preferredoriginID = preferredoriginIDElem.text
preferredmagID = None
preferredMagnitudeIDElem = root[0][0].find("ns:preferredMagnitudeID", ns)
if preferredMagnitudeIDElem:
preferredmagID = preferredMagnitudeIDElem.text
except AttributeError:
preferredfmID = None
preferredfmID = root[0][0].find("ns:preferredFocalMechanismID", ns).text
preferredfmIDElem = root[0][0].find("ns:preferredFocalMechanismID", ns)
if preferredfmIDElem:
preferredfmID = preferredfmIDElem.text
except AttributeError:
preferredfmID = None
if not preferredoriginID:
print("Oops, no preferredOriginID was found")
return None
origin = fetch_origin(root, ns, preferredoriginID)
(d, t) = origin.pop("time").split("T", 2)
......@@ -195,14 +234,16 @@ def fetch_quakeml(path):
# d =, 1, 1)
# t = datetime.time(12, 0, 30, 123000)
focalmech = None
if preferredfmID:
focalmech = fetch_fm(root, ns, preferredfmID)
focalmech = None
# Should this be event's preferred magnitude,
# or the preferred focal mechanism's <momentMagnitudeID>?
# Probably they are the same thing...
if not preferredmagID:
print("Oops, no preferredMagnitudeID was found")
return None
mag = fetch_magnitude(root, ns, preferredmagID)
return {
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment