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 2024-03-07 11:54 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2024-03-07 11:54 +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'''
33def to_pyrocko_trace(trace):
34 '''
35 Convert ObsPy trace object to Pyrocko trace object.
37 :param trace:
38 :py:class:`obspy.Trace <obspy.core.trace.Trace>` object
39 :returns:
40 :py:class:`pyrocko.trace.Trace` object
41 '''
42 obspy_trace = trace
43 from pyrocko import trace
45 return trace.Trace(
46 str(obspy_trace.stats.network),
47 str(obspy_trace.stats.station),
48 str(obspy_trace.stats.location),
49 str(obspy_trace.stats.channel),
50 tmin=obspy_trace.stats.starttime.timestamp,
51 tmax=obspy_trace.stats.endtime.timestamp,
52 ydata=obspy_trace.data,
53 deltat=obspy_trace.stats.delta)
56def to_pyrocko_traces(stream):
57 '''
58 Convert ObsPy stream object to list of Pyrocko trace objects.
60 :param stream:
61 :py:class:`obspy.Stream <obspy.core.stream.Stream>` object
62 :returns:
63 list of :py:class:`pyrocko.trace.Trace` objects
64 '''
66 obspy_stream = stream
68 return [to_pyrocko_trace(obspy_trace) for obspy_trace in obspy_stream]
71def to_pyrocko_events(catalog):
72 '''
73 Convert ObsPy catalog object to list of Pyrocko event objects.
75 :param catalog:
76 :py:class:`obspy.Catalog <obspy.core.event.Catalog>` object
77 :returns:
78 list of :py:class:`pyrocko.model.event.Event` objects or ``None`` if
79 catalog is ``None``
80 '''
82 obspy_catalog = catalog
84 if obspy_catalog is None:
85 return None
87 from pyrocko import model
89 events = []
90 for obspy_event in obspy_catalog:
91 for origin in obspy_event.origins:
93 events.append(model.Event(
94 name='%s-%s' % (obspy_event.resource_id, origin.resource_id),
95 time=origin.time.timestamp,
96 lat=origin.latitude,
97 lon=origin.longitude,
98 depth=origin.depth,
99 region=origin.region))
101 return events
104def to_pyrocko_stations(inventory):
105 '''
106 Convert ObsPy inventory to list of Pyrocko traces.
108 :param inventory:
109 :py:class:`obspy.Inventory <obspy.core.inventory.inventory.Inventory>`
110 object
111 :returns:
112 list of :py:class:`pyrocko.model.station.Station` objects or ``None``
113 if inventory is ``None``
114 '''
116 obspy_inventory = inventory
118 if obspy_inventory is None:
119 return None
121 from pyrocko import model
122 stations = []
123 for net in obspy_inventory.networks:
124 for sta in net.stations:
125 stations.append(
126 model.Station(
127 lat=sta.latitude,
128 lon=sta.longitude,
129 elevation=sta.elevation,
130 network=net.code,
131 station=sta.code,
132 location='',
133 channels=[
134 model.station.Channel(
135 name=cha.code,
136 azimuth=cha.azimuth,
137 dip=cha.dip) for cha in sta.channels]
138 ))
140 return stations
143def to_obspy_stream(pile):
144 '''
145 Convert Pyrocko pile to ObsPy stream.
147 :param pile:
148 :py:class:`pyrocko.pile.Pile` object
149 :returns:
150 :py:class:`obspy.Stream <obspy.core.stream.Stream>` object
151 '''
153 pyrocko_pile = pile
155 import obspy
156 stream = obspy.Stream()
157 stream.extend([to_obspy_trace(tr) for tr in pyrocko_pile.iter_all()])
158 return stream
161def to_obspy_trace(trace):
162 '''
163 Convert Pyrocko trace to ObsPy trace.
165 :param trace:
166 :py:class:`pyrocko.trace.Trace`
167 '''
168 import obspy
170 pyrocko_trace = trace
172 obspy_trace = obspy.Trace(
173 data=pyrocko_trace.ydata,
174 header=obspy.core.trace.Stats(
175 dict(
176 npts=len(pyrocko_trace.ydata),
177 network=pyrocko_trace.network,
178 station=pyrocko_trace.station,
179 location=pyrocko_trace.location,
180 channel=pyrocko_trace.channel,
181 delta=pyrocko_trace.deltat,
182 starttime=pyrocko_trace.tmin,
183 endtime=pyrocko_trace.tmax)
184 ))
186 return obspy_trace
189def snuffle(stream_or_trace, inventory=None, catalog=None, **kwargs):
190 '''
191 Explore ObsPy data with Snuffler.
193 :param stream_or_trace:
194 :py:class:`obspy.Stream <obspy.core.stream.Stream>` or
195 :py:class:`obspy.Trace <obspy.core.trace.Trace>` object
196 :param inventory:
197 :py:class:`obspy.Inventory <obspy.core.inventory.inventory.Inventory>`
198 object
199 :param catalog:
200 :py:class:`obspy.Catalog <obspy.core.event.Catalog>` object
201 :param kwargs:
202 extra arguments passed to :meth:`pyrocko.trace.Trace.snuffle`.
204 :returns:
205 ``(return_tag, markers)``, where ``return_tag`` is the a string to flag
206 how the Snuffler window has been closed and ``markers`` is a list of
207 :py:class:`pyrocko.gui.snuffler.marker.Marker` objects.
209 This function displays an ObsPy stream object in Snuffler. It returns to
210 the caller once the window has been closed. The ``return_tag`` returned by
211 the function can be used as a primitive way to communicate a user decision
212 to the calling script. By default it returns the key pressed to close the
213 window (if any), either ``'q'`` or ``'x'``, but the value could be
214 customized when the exit is triggered from within a Snuffling.
216 See also :py:func:`fiddle` for a variant of this function returning
217 an interactively modified ObsPy stream object.
218 '''
220 from pyrocko import trace
221 import obspy
223 obspy_inventory = inventory
224 obspy_catalog = catalog
226 if isinstance(stream_or_trace, obspy.Trace):
227 obspy_stream = obspy.core.stream.Stream(traces=[stream_or_trace])
228 else:
229 obspy_stream = stream_or_trace
231 events = to_pyrocko_events(obspy_catalog)
232 stations = to_pyrocko_stations(obspy_inventory)
234 return trace.snuffle(
235 to_pyrocko_traces(obspy_stream),
236 events=events,
237 stations=stations,
238 want_markers=True,
239 **kwargs)
242class ObsPyStreamSnufflingLoader(object):
244 def __init__(self, obspy_stream):
245 self.obspy_stream = obspy_stream
247 def __call__(self, win):
248 from .snuffling import ObsPyStreamSnuffling
249 self.snuffling = ObsPyStreamSnuffling(obspy_stream=self.obspy_stream)
250 self.snuffling.setup()
251 win.pile_viewer.viewer.add_snuffling(self.snuffling, reloaded=True)
253 def get_snuffling(self):
254 return self.snuffling
257def fiddle(stream_or_trace, inventory=None, catalog=None, **kwargs):
258 '''
259 Manipulate ObsPy stream object interactively.
261 :param stream_or_trace:
262 :py:class:`obspy.Stream <obspy.core.stream.Stream>` or
263 :py:class:`obspy.Trace <obspy.core.trace.Trace>` object
264 :param inventory:
265 :py:class:`obspy.Inventory <obspy.core.inventory.inventory.Inventory>`
266 object
267 :param catalog:
268 :py:class:`obspy.Catalog <obspy.core.event.Catalog>` object
269 :param kwargs:
270 extra arguments passed to :meth:`pyrocko.trace.Trace.snuffle`.
272 :returns: :py:class:`obspy.Stream <obspy.core.stream.Stream>` object with
273 changes applied interactively (or :py:class:`obspy.Trace
274 <obspy.core.trace.Trace>` if called with a trace as first argument).
276 This function displays an ObsPy stream object in Snuffler like
277 :py:func:`snuffle`, but additionally adds a Snuffling panel to apply some
278 basic ObsPy signal processing to the contained traces. The applied changes
279 are handed back to the caller as a modified copy of the stream object.
281 .. code::
283 import obspy
284 from pyrocko import obspy_compat
286 obspy_compat.plant()
288 stream = obspy.read()
289 stream_filtered = stream.fiddle() # returns once window has been
290 # closed
291 '''
293 from pyrocko import trace
294 import obspy
296 obspy_inventory = inventory
297 obspy_catalog = catalog
299 if isinstance(stream_or_trace, obspy.Trace):
300 obspy_stream = obspy.core.stream.Stream(traces=[stream_or_trace])
301 else:
302 obspy_stream = stream_or_trace
304 events = to_pyrocko_events(obspy_catalog)
305 stations = to_pyrocko_stations(obspy_inventory)
307 snuffling_loader = ObsPyStreamSnufflingLoader(obspy_stream)
308 launch_hook = kwargs.pop('launch_hook', [])
309 if not isinstance(launch_hook, list):
310 launch_hook = [launch_hook]
311 launch_hook.append(snuffling_loader)
313 trace.snuffle(
314 [],
315 events=events,
316 stations=stations,
317 controls=False,
318 launch_hook=launch_hook,
319 **kwargs)
321 new_obspy_stream = snuffling_loader.get_snuffling().get_obspy_stream()
323 if isinstance(obspy_stream, obspy.Trace):
324 return new_obspy_stream[0]
325 else:
326 return new_obspy_stream
329def plant():
330 '''
331 Add conversion functions as methods to ObsPy and Pyrocko classes.
333 Methods added to ObsPy classes are:
335 +------------------------------------------------------+---------------------------------+
336 | class | methods |
337 +======================================================+=================================+
338 | :py:class:`obspy.core.trace.Trace` | :py:func:`to_pyrocko_trace` |
339 | +---------------------------------+
340 | | :py:func:`snuffle` |
341 | +---------------------------------+
342 | | :py:func:`fiddle` |
343 +------------------------------------------------------+---------------------------------+
344 | :py:class:`obspy.core.stream.Stream` | :py:func:`to_pyrocko_traces` |
345 | +---------------------------------+
346 | | :py:func:`snuffle` |
347 | +---------------------------------+
348 | | :py:func:`fiddle` |
349 +------------------------------------------------------+---------------------------------+
350 | :py:class:`obspy.core.event.Catalog` | :py:func:`to_pyrocko_events` |
351 +------------------------------------------------------+---------------------------------+
352 | :py:class:`obspy.core.inventory.inventory.Inventory` | :py:func:`to_pyrocko_stations` |
353 +------------------------------------------------------+---------------------------------+
355 Methods added to Pyrocko classes are:
357 +--------------------------------------+---------------------------------+
358 | class | methods |
359 +======================================+=================================+
360 | :py:class:`pyrocko.trace.Trace` | :py:func:`to_obspy_trace` |
361 +--------------------------------------+---------------------------------+
362 | :py:class:`pyrocko.pile.Pile` | :py:func:`to_obspy_stream` |
363 +--------------------------------------+---------------------------------+
364 ''' # noqa
366 import obspy
367 obspy.Trace.to_pyrocko_trace = to_pyrocko_trace
368 obspy.Trace.snuffle = snuffle
369 obspy.Trace.fiddle = fiddle
371 obspy.Stream.to_pyrocko_traces = to_pyrocko_traces
372 obspy.Stream.snuffle = snuffle
373 obspy.Stream.fiddle = fiddle
375 obspy.core.event.Catalog.to_pyrocko_events = to_pyrocko_events
376 obspy.core.inventory.inventory.Inventory.to_pyrocko_stations =\
377 to_pyrocko_stations
379 import pyrocko.trace
380 import pyrocko.pile
381 pyrocko.trace.Trace.to_obspy_trace = to_obspy_trace
382 pyrocko.pile.Pile.to_obspy_stream = to_obspy_stream
385__all__ = [
386 'to_pyrocko_trace',
387 'to_pyrocko_traces',
388 'to_pyrocko_events',
389 'to_pyrocko_stations',
390 'to_obspy_stream',
391 'to_obspy_trace',
392 'snuffle',
393 'fiddle',
394 'plant']