Coverage for /usr/local/lib/python3.11/dist-packages/pyrocko/obspy_compat/base.py: 99%
95 statements
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-04 09:52 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2023-10-04 09:52 +0000
1# https://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
6'''
7This module provides basic compatibility between ObsPy and Pyrocko.
9The functions defined here can be used to translate back and forth some of the
10basic objects in Pyrocko and ObsPy. It also provides shortcuts to quickly look
11at ObsPy waveforms with the Pyrocko's :doc:`Snuffler </apps/snuffler/index>`
12application (:py:func:`snuffle`, :py:func:`fiddle`).
14With :func:`~pyrocko.obspy_compat.base.plant` several new methods are attached
15to Pyrocko and ObsPy classes.
17**Example, visualize ObsPy stream object with Snuffler:**
19.. code-block:: python
21 import obspy
22 from pyrocko import obspy_compat
23 obspy_compat.plant()
25 stream = obspy.read() # returns some example data
26 stream.snuffle()
28-- *With best wishes to the ObsPy Team from the Pyrocko Developers!*
30.. note::
32 This is an experimental module, the interface may still be changed.
33 Feedback and discussion welcome!
35'''
38def to_pyrocko_trace(trace):
39 '''
40 Convert ObsPy trace object to Pyrocko trace object.
42 :param trace:
43 :py:class:`obspy.Trace <obspy.core.trace.Trace>` object
44 :returns:
45 :py:class:`pyrocko.trace.Trace` object
46 '''
47 obspy_trace = trace
48 from pyrocko import trace
50 return trace.Trace(
51 str(obspy_trace.stats.network),
52 str(obspy_trace.stats.station),
53 str(obspy_trace.stats.location),
54 str(obspy_trace.stats.channel),
55 tmin=obspy_trace.stats.starttime.timestamp,
56 tmax=obspy_trace.stats.endtime.timestamp,
57 ydata=obspy_trace.data,
58 deltat=obspy_trace.stats.delta)
61def to_pyrocko_traces(stream):
62 '''
63 Convert ObsPy stream object to list of Pyrocko trace objects.
65 :param stream:
66 :py:class:`obspy.Stream <obspy.core.stream.Stream>` object
67 :returns:
68 list of :py:class:`pyrocko.trace.Trace` objects
69 '''
71 obspy_stream = stream
73 return [to_pyrocko_trace(obspy_trace) for obspy_trace in obspy_stream]
76def to_pyrocko_events(catalog):
77 '''
78 Convert ObsPy catalog object to list of Pyrocko event objects.
80 :param catalog:
81 :py:class:`obspy.Catalog <obspy.core.event.Catalog>` object
82 :returns:
83 list of :py:class:`pyrocko.model.event.Event` objects or ``None`` if
84 catalog is ``None``
85 '''
87 obspy_catalog = catalog
89 if obspy_catalog is None:
90 return None
92 from pyrocko import model
94 events = []
95 for obspy_event in obspy_catalog:
96 for origin in obspy_event.origins:
98 events.append(model.Event(
99 name='%s-%s' % (obspy_event.resource_id, origin.resource_id),
100 time=origin.time.timestamp,
101 lat=origin.latitude,
102 lon=origin.longitude,
103 depth=origin.depth,
104 region=origin.region))
106 return events
109def to_pyrocko_stations(inventory):
110 '''
111 Convert ObsPy inventory to list of Pyrocko traces.
113 :param inventory:
114 :py:class:`obspy.Inventory <obspy.core.inventory.inventory.Inventory>`
115 object
116 :returns:
117 list of :py:class:`pyrocko.model.station.Station` objects or ``None``
118 if inventory is ``None``
119 '''
121 obspy_inventory = inventory
123 if obspy_inventory is None:
124 return None
126 from pyrocko import model
127 stations = []
128 for net in obspy_inventory.networks:
129 for sta in net.stations:
130 stations.append(
131 model.Station(
132 lat=sta.latitude,
133 lon=sta.longitude,
134 elevation=sta.elevation,
135 network=net.code,
136 station=sta.code,
137 location='',
138 channels=[
139 model.station.Channel(
140 name=cha.code,
141 azimuth=cha.azimuth,
142 dip=cha.dip) for cha in sta.channels]
143 ))
145 return stations
148def to_obspy_stream(pile):
149 '''
150 Convert Pyrocko pile to ObsPy stream.
152 :param pile:
153 :py:class:`pyrocko.pile.Pile` object
154 :returns:
155 :py:class:`obspy.Stream <obspy.core.stream.Stream>` object
156 '''
158 pyrocko_pile = pile
160 import obspy
161 stream = obspy.Stream()
162 stream.extend([to_obspy_trace(tr) for tr in pyrocko_pile.iter_all()])
163 return stream
166def to_obspy_trace(trace):
167 '''
168 Convert Pyrocko trace to ObsPy trace.
170 :param trace:
171 :py:class:`pyrocko.trace.Trace`
172 '''
173 import obspy
175 pyrocko_trace = trace
177 obspy_trace = obspy.Trace(
178 data=pyrocko_trace.ydata,
179 header=obspy.core.trace.Stats(
180 dict(
181 npts=len(pyrocko_trace.ydata),
182 network=pyrocko_trace.network,
183 station=pyrocko_trace.station,
184 location=pyrocko_trace.location,
185 channel=pyrocko_trace.channel,
186 delta=pyrocko_trace.deltat,
187 starttime=pyrocko_trace.tmin,
188 endtime=pyrocko_trace.tmax)
189 ))
191 return obspy_trace
194def snuffle(stream_or_trace, inventory=None, catalog=None, **kwargs):
195 '''
196 Explore ObsPy data with Snuffler.
198 :param stream_or_trace:
199 :py:class:`obspy.Stream <obspy.core.stream.Stream>` or
200 :py:class:`obspy.Trace <obspy.core.trace.Trace>` object
201 :param inventory:
202 :py:class:`obspy.Inventory <obspy.core.inventory.inventory.Inventory>`
203 object
204 :param catalog:
205 :py:class:`obspy.Catalog <obspy.core.event.Catalog>` object
206 :param kwargs:
207 extra arguments passed to :meth:`pyrocko.trace.Trace.snuffle`.
209 :returns:
210 ``(return_tag, markers)``, where ``return_tag`` is the a string to flag
211 how the Snuffler window has been closed and ``markers`` is a list of
212 :py:class:`pyrocko.gui.snuffler.marker.Marker` objects.
214 This function displays an ObsPy stream object in Snuffler. It returns to
215 the caller once the window has been closed. The ``return_tag`` returned by
216 the function can be used as a primitive way to communicate a user decision
217 to the calling script. By default it returns the key pressed to close the
218 window (if any), either ``'q'`` or ``'x'``, but the value could be
219 customized when the exit is triggered from within a Snuffling.
221 See also :py:func:`fiddle` for a variant of this function returning
222 an interactively modified ObsPy stream object.
223 '''
225 from pyrocko import trace
226 import obspy
228 obspy_inventory = inventory
229 obspy_catalog = catalog
231 if isinstance(stream_or_trace, obspy.Trace):
232 obspy_stream = obspy.core.stream.Stream(traces=[stream_or_trace])
233 else:
234 obspy_stream = stream_or_trace
236 events = to_pyrocko_events(obspy_catalog)
237 stations = to_pyrocko_stations(obspy_inventory)
239 return trace.snuffle(
240 to_pyrocko_traces(obspy_stream),
241 events=events,
242 stations=stations,
243 want_markers=True,
244 **kwargs)
247class ObsPyStreamSnufflingLoader(object):
249 def __init__(self, obspy_stream):
250 self.obspy_stream = obspy_stream
252 def __call__(self, win):
253 from .snuffling import ObsPyStreamSnuffling
254 self.snuffling = ObsPyStreamSnuffling(obspy_stream=self.obspy_stream)
255 self.snuffling.setup()
256 win.pile_viewer.viewer.add_snuffling(self.snuffling, reloaded=True)
258 def get_snuffling(self):
259 return self.snuffling
262def fiddle(stream_or_trace, inventory=None, catalog=None, **kwargs):
263 '''
264 Manipulate ObsPy stream object interactively.
266 :param stream_or_trace:
267 :py:class:`obspy.Stream <obspy.core.stream.Stream>` or
268 :py:class:`obspy.Trace <obspy.core.trace.Trace>` object
269 :param inventory:
270 :py:class:`obspy.Inventory <obspy.core.inventory.inventory.Inventory>`
271 object
272 :param catalog:
273 :py:class:`obspy.Catalog <obspy.core.event.Catalog>` object
274 :param kwargs:
275 extra arguments passed to :meth:`pyrocko.trace.Trace.snuffle`.
277 :returns: :py:class:`obspy.Stream <obspy.core.stream.Stream>` object with
278 changes applied interactively (or :py:class:`obspy.Trace
279 <obspy.core.trace.Trace>` if called with a trace as first argument).
281 This function displays an ObsPy stream object in Snuffler like
282 :py:func:`snuffle`, but additionally adds a Snuffling panel to apply some
283 basic ObsPy signal processing to the contained traces. The applied changes
284 are handed back to the caller as a modified copy of the stream object.
286 .. code::
288 import obspy
289 from pyrocko import obspy_compat
291 obspy_compat.plant()
293 stream = obspy.read()
294 stream_filtered = stream.fiddle() # returns once window has been
295 # closed
296 '''
298 from pyrocko import trace
299 import obspy
301 obspy_inventory = inventory
302 obspy_catalog = catalog
304 if isinstance(stream_or_trace, obspy.Trace):
305 obspy_stream = obspy.core.stream.Stream(traces=[stream_or_trace])
306 else:
307 obspy_stream = stream_or_trace
309 events = to_pyrocko_events(obspy_catalog)
310 stations = to_pyrocko_stations(obspy_inventory)
312 snuffling_loader = ObsPyStreamSnufflingLoader(obspy_stream)
313 launch_hook = kwargs.pop('launch_hook', [])
314 if not isinstance(launch_hook, list):
315 launch_hook = [launch_hook]
316 launch_hook.append(snuffling_loader)
318 trace.snuffle(
319 [],
320 events=events,
321 stations=stations,
322 controls=False,
323 launch_hook=launch_hook,
324 **kwargs)
326 new_obspy_stream = snuffling_loader.get_snuffling().get_obspy_stream()
328 if isinstance(obspy_stream, obspy.Trace):
329 return new_obspy_stream[0]
330 else:
331 return new_obspy_stream
334def plant():
335 '''
336 Add conversion functions as methods to ObsPy and Pyrocko classes.
338 Methods added to ObsPy classes are:
340 +------------------------------------------------------+---------------------------------+
341 | class | methods |
342 +======================================================+=================================+
343 | :py:class:`obspy.core.trace.Trace` | :py:func:`to_pyrocko_trace` |
344 | +---------------------------------+
345 | | :py:func:`snuffle` |
346 | +---------------------------------+
347 | | :py:func:`fiddle` |
348 +------------------------------------------------------+---------------------------------+
349 | :py:class:`obspy.core.stream.Stream` | :py:func:`to_pyrocko_traces` |
350 | +---------------------------------+
351 | | :py:func:`snuffle` |
352 | +---------------------------------+
353 | | :py:func:`fiddle` |
354 +------------------------------------------------------+---------------------------------+
355 | :py:class:`obspy.core.event.Catalog` | :py:func:`to_pyrocko_events` |
356 +------------------------------------------------------+---------------------------------+
357 | :py:class:`obspy.core.inventory.inventory.Inventory` | :py:func:`to_pyrocko_stations` |
358 +------------------------------------------------------+---------------------------------+
360 Methods added to Pyrocko classes are:
362 +--------------------------------------+---------------------------------+
363 | class | methods |
364 +======================================+=================================+
365 | :py:class:`pyrocko.trace.Trace` | :py:func:`to_obspy_trace` |
366 +--------------------------------------+---------------------------------+
367 | :py:class:`pyrocko.pile.Pile` | :py:func:`to_obspy_stream` |
368 +--------------------------------------+---------------------------------+
369 ''' # noqa
371 import obspy
372 obspy.Trace.to_pyrocko_trace = to_pyrocko_trace
373 obspy.Trace.snuffle = snuffle
374 obspy.Trace.fiddle = fiddle
376 obspy.Stream.to_pyrocko_traces = to_pyrocko_traces
377 obspy.Stream.snuffle = snuffle
378 obspy.Stream.fiddle = fiddle
380 obspy.core.event.Catalog.to_pyrocko_events = to_pyrocko_events
381 obspy.core.inventory.inventory.Inventory.to_pyrocko_stations =\
382 to_pyrocko_stations
384 import pyrocko.trace
385 import pyrocko.pile
386 pyrocko.trace.Trace.to_obspy_trace = to_obspy_trace
387 pyrocko.pile.Pile.to_obspy_stream = to_obspy_stream
390__all__ = [
391 'to_pyrocko_trace',
392 'to_pyrocko_traces',
393 'to_pyrocko_events',
394 'to_pyrocko_stations',
395 'to_obspy_stream',
396 'to_obspy_trace',
397 'snuffle',
398 'fiddle',
399 'plant']