Skip to content

Commit

Permalink
Move warning from _is_sc3ml to _read_sc3ml
Browse files Browse the repository at this point in the history
The XSLT conversion with a wrong namespace returns an empty SC3ML. Since there
isn't an EventParameters node, the QuakeML module raise an exception. So The
warnings have also been replaced by exceptions.

See #1873.
  • Loading branch information
Brtle committed Sep 18, 2017
1 parent ee71bd1 commit 0889d21
Show file tree
Hide file tree
Showing 13 changed files with 53 additions and 112 deletions.
17 changes: 2 additions & 15 deletions obspy/io/seiscomp/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import os
import re
import warnings

from lxml import etree

Expand All @@ -28,7 +27,7 @@
SUPPORTED_XSD_VERSION = ['0.3', '0.5', '0.6', '0.7', '0.8', '0.9']


def _is_sc3ml(path_or_file_object, schema_versions):
def _is_sc3ml(path_or_file_object):
"""
Simple function checking if the passed object contains a valid sc3ml file
according to the list of versions given in parameters. Returns True of
Expand All @@ -41,8 +40,6 @@ def _is_sc3ml(path_or_file_object, schema_versions):
:type path_or_file_object: str
:param path_or_file_object: File name or file like object.
:type schema_versions: list of strings
:param schema_versions: List of supported SC3ML version.
:rtype: bool
:return: `True` if file is a SC3ML file.
"""
Expand Down Expand Up @@ -73,17 +70,7 @@ def _is_sc3ml(path_or_file_object, schema_versions):
r'{http://geofon\.gfz-potsdam\.de/ns/seiscomp3-schema/([-+]?'
r'[0-9]*\.?[0-9]+)}', root.tag)

if match is None:
return False

# Check if schema version is supported
version = match.group(1)
if version not in schema_versions:
warnings.warn('The sc3ml file has version %s, ObsPy can '
'deal with versions [%s]. Proceed with caution.' % (
version, ', '.join(schema_versions)))

return True
return match is not None


def validate(path_or_object, version='0.9', verbose=False):
Expand Down
30 changes: 5 additions & 25 deletions obspy/io/seiscomp/event.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,16 @@
import io
import os
import re
import warnings

from lxml import etree

from obspy.io.quakeml.core import Pickler, Unpickler, _xml_doc_from_anything
from obspy.io.seiscomp.core import _is_sc3ml as _is_sc3ml_version
from obspy.io.seiscomp.core import validate as validate_sc3ml


SCHEMA_VERSION = ['0.5', '0.6', '0.7', '0.8', '0.9']


def _is_sc3ml(path_or_file_object):
"""
Simple function checking if the passed object contains a valid sc3ml file.
Returns True of False.
The test is not exhaustive - it only checks the root tag but that should
be good enough for most real world use cases. If the schema is used to
test for a StationXML file, many real world files are false negatives as
they don't adhere to the standard.
:type path_or_file_object: str
:param path_or_file_object: File name or file like object.
:rtype: bool
:return: ``True`` if SC3ML file is valid.
"""
return _is_sc3ml_version(path_or_file_object, SCHEMA_VERSION)


def _read_sc3ml(filename, id_prefix='smi:org.gfz-potsdam.de/geofon/'):
"""
Read a 0.9 SC3ML file and returns a :class:`~obspy.core.event.Catalog`.
Expand Down Expand Up @@ -89,13 +69,13 @@ def _read_sc3ml(filename, id_prefix='smi:org.gfz-potsdam.de/geofon/'):
try:
version = match.group(1)
except AttributeError:
warnings.warn('The file does not appear to be a SC3ML file. Proceed '
'with caution.')
version = SCHEMA_VERSION[-1]
raise ValueError("Not a SC3ML compatible file or string.")
else:
if version not in SCHEMA_VERSION:
# By default, try to convert with the latest version
version = SCHEMA_VERSION[-1]
message = ("Can't read SC3ML version %s, ObsPy can deal with "
"versions [%s].") % (
version, ', '.join(SCHEMA_VERSION))
raise ValueError(message)

xslt_filename = os.path.join(os.path.dirname(__file__), 'data',
'sc3ml_%s__quakeml_1.2.xsl' % version)
Expand Down
19 changes: 0 additions & 19 deletions obspy/io/seiscomp/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,32 +32,13 @@
PolesZerosResponseStage,
PolynomialResponseStage)
from obspy.io.stationxml.core import _read_floattype
from obspy.io.seiscomp.core import _is_sc3ml as _is_sc3ml_version


SOFTWARE_MODULE = "ObsPy %s" % obspy.__version__
SOFTWARE_URI = "http://www.obspy.org"
SCHEMA_VERSION = ['0.5', '0.6', '0.7', '0.8', '0.9']


def _is_sc3ml(path_or_file_object):
"""
Simple function checking if the passed object contains a valid sc3ml file.
Returns True of False.
The test is not exhaustive - it only checks the root tag but that should
be good enough for most real world use cases. If the schema is used to
test for a StationXML file, many real world files are false negatives as
they don't adhere to the standard.
:type path_or_file_object: str
:param path_or_file_object: File name or file like object.
:rtype: bool
:return: ``True`` if SC3ML file is valid.
"""
return _is_sc3ml_version(path_or_file_object, SCHEMA_VERSION)


def _read_sc3ml(path_or_file_object):
"""
Function for reading a stationXML file.
Expand Down
4 changes: 2 additions & 2 deletions obspy/io/seiscomp/tests/data/version0.10
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<seiscomp xmlns="http://geofon.gfz-potsdam.de/ns/seiscomp3-schema/0.10" version="0.10">
<Inventory>
</Inventory>
<EventParameters />
<Inventory />
</seiscomp>
4 changes: 2 additions & 2 deletions obspy/io/seiscomp/tests/data/version0.3
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<seiscomp xmlns="http://geofon.gfz-potsdam.de/ns/seiscomp3-schema/0.3" version="0.3">
<Inventory>
</Inventory>
<EventParameters />
<Inventory />
</seiscomp>
4 changes: 2 additions & 2 deletions obspy/io/seiscomp/tests/data/version0.5
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<seiscomp xmlns="http://geofon.gfz-potsdam.de/ns/seiscomp3-schema/0.5" version="0.5">
<Inventory>
</Inventory>
<EventParameters />
<Inventory />
</seiscomp>
4 changes: 2 additions & 2 deletions obspy/io/seiscomp/tests/data/version0.6
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<seiscomp xmlns="http://geofon.gfz-potsdam.de/ns/seiscomp3-schema/0.6" version="0.6">
<Inventory>
</Inventory>
<EventParameters />
<Inventory />
</seiscomp>
4 changes: 2 additions & 2 deletions obspy/io/seiscomp/tests/data/version0.7
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<seiscomp xmlns="http://geofon.gfz-potsdam.de/ns/seiscomp3-schema/0.7" version="0.7">
<Inventory>
</Inventory>
<EventParameters />
<Inventory />
</seiscomp>
4 changes: 2 additions & 2 deletions obspy/io/seiscomp/tests/data/version0.8
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<seiscomp xmlns="http://geofon.gfz-potsdam.de/ns/seiscomp3-schema/0.8" version="0.8">
<Inventory>
</Inventory>
<EventParameters />
<Inventory />
</seiscomp>
4 changes: 2 additions & 2 deletions obspy/io/seiscomp/tests/data/version0.9
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<seiscomp xmlns="http://geofon.gfz-potsdam.de/ns/seiscomp3-schema/0.9" version="0.9">
<Inventory>
</Inventory>
<EventParameters />
<Inventory />
</seiscomp>
31 changes: 4 additions & 27 deletions obspy/io/seiscomp/tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

import os
import unittest
import warnings

from obspy.io.seiscomp.core import _is_sc3ml, validate

Expand All @@ -33,35 +32,13 @@ def test_sc3ml_versions(self):
"""
Test multiple schema versions
"""
filename_07 = os.path.join(self.data_dir, 'version0.7')
filename_08 = os.path.join(self.data_dir, 'version0.8')
filename_09 = os.path.join(self.data_dir, 'version0.9')

self.assertTrue(_is_sc3ml(filename_07, ['0.7', '0.8']))
self.assertTrue(_is_sc3ml(filename_08, ['0.7', '0.8']))

with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
self.assertTrue(_is_sc3ml(filename_09, ['0.7', '0.8']))

self.assertEqual(len(w), 1)
expected_message = ("The sc3ml file has version 0.9, ObsPy can "
"deal with versions [0.7, 0.8]. Proceed "
"with caution.")
self.assertEqual(str(w[0].message), expected_message)

with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
self.assertTrue(_is_sc3ml(filename_09, []))

self.assertEqual(len(w), 1)
expected_message = ("The sc3ml file has version 0.9, ObsPy can "
"deal with versions []. Proceed with caution.")
self.assertEqual(str(w[0].message), expected_message)
for version in ['0.3', '0.5', '0.9', '0.10']:
filename = os.path.join(self.data_dir, 'version%s' % version)
self.assertTrue(_is_sc3ml(filename))

def test_sc3ml_no_version_attribute(self):
filename = os.path.join(self.data_dir, 'no_version_attribute.sc3ml')
self.assertTrue(_is_sc3ml(filename, ['0.9']))
self.assertTrue(_is_sc3ml(filename))

def test_validate(self):
filename = os.path.join(self.data_dir, 'qml-example-1.2-RC3.sc3ml')
Expand Down
36 changes: 26 additions & 10 deletions obspy/io/seiscomp/tests/test_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from obspy.io.quakeml.core import _read_quakeml
from obspy.io.quakeml.core import _validate as _validate_quakeml
from obspy.io.seiscomp.core import validate as validate_sc3ml
from obspy.io.seiscomp.event import _is_sc3ml, _read_sc3ml
from obspy.io.seiscomp.event import _read_sc3ml


class EventTestCase(unittest.TestCase):
Expand Down Expand Up @@ -88,18 +88,23 @@ def test_sc3ml_versions(self):
"""
for version in ['0.5', '0.6', '0.7', '0.8', '0.9']:
filename = os.path.join(self.path, 'version%s' % version)
self.assertTrue(_is_sc3ml(filename))
read_events(filename)

for version in ['0.3', '0.10']:
filename = os.path.join(self.path, 'version%s' % version)
filename = os.path.join(self.path, 'version0.3')
with self.assertRaises(ValueError) as e:
read_events(filename)

expected_message = ("Can't read SC3ML version 0.3, ObsPy can deal "
"with versions [0.5, 0.6, 0.7, 0.8, 0.9].")
self.assertEqual(e.exception.args[0], expected_message)

with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
self.assertTrue(_is_sc3ml(filename))
filename = os.path.join(self.path, 'version0.10')
with self.assertRaises(ValueError) as e:
read_events(filename)

self.assertEqual(len(w), 1)
expected_message = 'The sc3ml file has version'
self.assertTrue(str(w[0].message).startswith(expected_message))
expected_message = ("Can't read SC3ML version 0.10, ObsPy can deal"
" with versions [0.5, 0.6, 0.7, 0.8, 0.9].")
self.assertEqual(e.exception.args[0], expected_message)

def test_read_xslt_event(self):
self.cmp_read_xslt_file('quakeml_1.2_event.sc3ml',
Expand Down Expand Up @@ -196,6 +201,17 @@ def test_read_string(self):
catalog = read_events(data)
self.assertEqual(len(catalog), 1)

def test_read_quakeml(self):
"""
Test reading a QuakeML file via read_events.
"""
filename = os.path.join(self.path, 'qml-example-1.2-RC3.xml')
with self.assertRaises(ValueError) as e:
read_events(filename, format='SC3ML')

expected_message = "Not a SC3ML compatible file or string."
self.assertEqual(e.exception.args[0], expected_message)

def test_write_xslt_event(self):
self.cmp_write_xslt_file('quakeml_1.2_event.xml',
'quakeml_1.2_event.sc3ml',
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@
'writeFormat = obspy.io.quakeml.core:_write_quakeml',
],
'obspy.plugin.event.SC3ML': [
'isFormat = obspy.io.seiscomp.event:_is_sc3ml',
'isFormat = obspy.io.seiscomp.core:_is_sc3ml',
'readFormat = obspy.io.seiscomp.event:_read_sc3ml',
'writeFormat = obspy.io.seiscomp.event:_write_sc3ml',
],
Expand Down Expand Up @@ -384,7 +384,7 @@
'readFormat = obspy.io.arclink.inventory:_read_inventory_xml',
],
'obspy.plugin.inventory.SC3ML': [
'isFormat = obspy.io.seiscomp.inventory:_is_sc3ml',
'isFormat = obspy.io.seiscomp.core:_is_sc3ml',
'readFormat = obspy.io.seiscomp.inventory:_read_sc3ml',
],
'obspy.plugin.inventory.SACPZ': [
Expand Down

0 comments on commit 0889d21

Please sign in to comment.