Repository: obspy/obspy

Issue:
use preferredOriginID correctly
After reading an quakeML file the preferred origin has to be selected correctly (may also have to be corrected in outputting to quakeML)



Discussion:
Also needs to be done for the Magnitude and potentially for some other objects as well.


Resolving patch:
diff --git a/obspy/core/event.py b/obspy/core/event.py
--- a/obspy/core/event.py
+++ b/obspy/core/event.py
@@ -2154,15 +2154,18 @@ def short_str(self):
         2011-03-11T05:46:24.120000Z | +38.297, +142.373 | 9.1 MW
         """
         out = ''
+        origin = None
         if self.origins:
-            out += '%s | %+7.3f, %+8.3f' % (self.origins[0].time,
-                                            self.origins[0].latitude,
-                                            self.origins[0].longitude)
+            origin = self.preferred_origin() or self.origins[0]
+            out += '%s | %+7.3f, %+8.3f' % (origin.time,
+                                            origin.latitude,
+                                            origin.longitude)
         if self.magnitudes:
-            out += ' | %s %-2s' % (self.magnitudes[0].mag,
-                                   self.magnitudes[0].magnitude_type)
-        if self.origins and self.origins[0].evaluation_mode:
-            out += ' | %s' % (self.origins[0].evaluation_mode)
+            magnitude = self.preferred_magnitude() or self.magnitudes[0]
+            out += ' | %s %-2s' % (magnitude.mag,
+                                   magnitude.magnitude_type)
+        if origin and origin.evaluation_mode:
+            out += ' | %s' % (origin.evaluation_mode)
         return out
 
     def __str__(self):
@@ -2172,6 +2175,35 @@ def __str__(self):
         return "Event:\t%s\n\n%s" % (self.short_str(),
             "\n".join(super(Event, self).__str__().split("\n")[1:]))
 
+    def preferred_origin(self):
+        """
+        Returns the preferred origin
+        """
+        try:
+            return ResourceIdentifier(self.preferred_origin_id).getReferredObject()
+        except KeyError:
+            return None
+
+    def preferred_magnitude(self):
+        """
+        Returns the preferred origin
+        """
+        try:
+            return ResourceIdentifier(self.preferred_magnitude_id).\
+                getReferredObject()
+        except KeyError:
+            return None
+
+    def preferred_focal_mechanism(self):
+        """
+        Returns the preferred origin
+        """
+        try:
+            return ResourceIdentifier(self.preferred_focal_mechanism_id).\
+                getReferredObject()
+        except KeyError:
+            return None
+
 
 class Catalog(object):
     """


Test patch:
diff --git a/obspy/core/tests/data/preferred.xml b/obspy/core/tests/data/preferred.xml
new file mode 100644
--- /dev/null
+++ b/obspy/core/tests/data/preferred.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<q:quakeml xmlns:q="http://quakeml.org/xmlns/quakeml/1.2"
+  xmlns="http://quakeml.org/xmlns/bed/1.2">
+  <eventParameters publicID="smi:www.iris.edu/ws/event/query">
+    <event publicID="smi:www.iris.edu/ws/event/query?eventId=3279407">
+      <type>earthquake</type>
+      <description xmlns:iris="http://www.iris.edu/ws/event" iris:FEcode="228">
+        <type>Flinn-Engdahl region</type>
+        <text>NEAR EAST COAST OF HONSHU, JAPAN</text>
+      </description>
+      <preferredOriginID>smi:orig2</preferredOriginID>
+      <preferredMagnitudeID>smi:mag2</preferredMagnitudeID>
+      <preferredFocalMechanismID>smi:fm2</preferredFocalMechanismID>
+      <origin xmlns:iris="http://www.iris.edu/ws/event"
+        publicID="smi:orig1"
+        iris:contributor="NEIC PDE-W" iris:catalog="NEIC PDE">
+        <time>
+          <value>2011-11-11T05:46:24.1200</value>
+        </time>
+        <creationInfo>
+          <author>1111</author>
+        </creationInfo>
+        <latitude>
+          <value>38.297</value>
+        </latitude>
+        <longitude>
+          <value>142.373</value>
+        </longitude>
+        <depth>
+          <value>29.0</value>
+        </depth>
+      </origin>
+      <origin xmlns:iris="http://www.iris.edu/ws/event"
+        publicID="smi:orig2"
+        iris:contributor="NEIC PDE-W" iris:catalog="NEIC PDE">
+        <time>
+          <value>2012-12-12T05:46:24.1200</value>
+        </time>
+        <creationInfo>
+          <author>2222</author>
+        </creationInfo>
+        <latitude>
+          <value>38.297</value>
+        </latitude>
+        <longitude>
+          <value>142.373</value>
+        </longitude>
+        <depth>
+          <value>29.0</value>
+        </depth>
+      </origin>
+      <magnitude
+        publicID="smi:mag1">
+        <type>MW</type>
+        <mag>
+          <value>1</value>
+        </mag>
+        <creationInfo>
+          <author>GCMT</author>
+        </creationInfo>
+      </magnitude>
+      <magnitude
+        publicID="smi:mag2">
+        <type>MW</type>
+        <mag>
+          <value>2</value>
+        </mag>
+        <creationInfo>
+          <author>GCMT</author>
+        </creationInfo>
+      </magnitude>
+      <focalMechanism publicID="smi:fm1">
+        <waveformID networkCode="BW" stationCode="FUR"
+          >smi:ch.ethz.sed/waveform/201754</waveformID>
+        <triggeringOriginID>smi:originId=7680412</triggeringOriginID>
+        <azimuthalGap>0.123</azimuthalGap>
+        <stationPolarityCount>987</stationPolarityCount>
+        <misfit>1</misfit>
+        <stationDistributionRatio>2.345</stationDistributionRatio>
+        <methodID>smi:ISC/methodID=Best_double_couple</methodID>
+      </focalMechanism>
+      <focalMechanism publicID="smi:fm2">
+        <waveformID networkCode="BW" stationCode="FUR"
+          >smi:ch.ethz.sed/waveform/201754</waveformID>
+        <triggeringOriginID>smi:originId=7680412</triggeringOriginID>
+        <azimuthalGap>0.123</azimuthalGap>
+        <stationPolarityCount>987</stationPolarityCount>
+        <misfit>2</misfit>
+        <stationDistributionRatio>2.345</stationDistributionRatio>
+        <methodID>smi:ISC/methodID=Best_double_couple</methodID>
+      </focalMechanism>
+    </event>
+  </eventParameters>
+</q:quakeml>
diff --git a/obspy/core/tests/test_quakeml.py b/obspy/core/tests/test_quakeml.py
--- a/obspy/core/tests/test_quakeml.py
+++ b/obspy/core/tests/test_quakeml.py
@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 
-from obspy.core.event import ResourceIdentifier, WaveformStreamID, readEvents
+from obspy.core.event import ResourceIdentifier, WaveformStreamID, \
+    readEvents, Event
 from obspy.core.quakeml import readQuakeML, Pickler, writeQuakeML
 from obspy.core.utcdatetime import UTCDateTime
 from obspy.core.util.base import NamedTemporaryFile
@@ -561,7 +562,33 @@ def test_read_string(self):
         filename = os.path.join(self.path, 'neries_events.xml')
         data = open(filename, 'rt').read()
         catalog = readEvents(data)
-        self.assertTrue(len(catalog), 3)
+        self.assertEquals(len(catalog), 3)
+
+    def test_preferred_tags(self):
+        """
+        Testing preferred magnitude, origin and focal mechanism tags
+        """
+        # testing empty event
+        ev = Event()
+        self.assertEquals(ev.preferred_origin(), None)
+        self.assertEquals(ev.preferred_magnitude(), None)
+        self.assertEquals(ev.preferred_focal_mechanism(), None)
+        # testing existing event
+        filename = os.path.join(self.path, 'preferred.xml')
+        catalog = readEvents(filename)
+        self.assertEquals(len(catalog), 1)
+        ev_str = "Event:\t2012-12-12T05:46:24.120000Z | +38.297, +142.373 | 2.0 MW"
+        self.assertTrue(ev_str in str(catalog.events[0]))
+        # testing ids
+        ev = catalog.events[0]
+        self.assertEquals('smi:orig2', ev.preferred_origin_id)
+        self.assertEquals('smi:mag2', ev.preferred_magnitude_id)
+        self.assertEquals('smi:fm2', ev.preferred_focal_mechanism_id)
+        # testing objects
+        self.assertEquals(ev.preferred_origin(), ev.origins[1])
+        self.assertEquals(ev.preferred_magnitude(), ev.magnitudes[1])
+        self.assertEquals(ev.preferred_focal_mechanism(),
+            ev.focal_mechanisms[1])
 
 
 def suite():