Extending Snuffler with plugins: Snufflings

Snufflings are small Python scripts which extend the functionality of Snuffler. Snuffler looks into the directory $HOME/.snufflings for snufflings. Snufflings can be reloaded at run-time using the menu entry ‘Reload Snufflings’ in the main menu of Snuffler - no need to restart Snuffler when a snuffling is modified or added.

Already existing snufflings can be downloaded from the snuffling repository

Example Snuffling to show earthquake catalog information within Snuffler

Put the following code into $HOME/.snufflings/geofon.py. It will add four items into the Snufflings sub-menu of Snuffler (Get GEOFON events, Get GEOFON events (> M6), …). When one of these is selected by the user, the GEOFON catalog is queried for earthquake information for the time range visible in Snuffler. For each earthquake found, a marker is shown in the viewer.

from pyrocko.gui.snuffler.snuffling import Snuffling, Param
from pyrocko.gui.snuffler.pile_viewer import Marker, EventMarker
from pyrocko.client import catalog

class GeofonEvents(Snuffling):

    '''
    Get events from GEOFON catalog.
    '''

    def __init__(self, magmin=None):
        self._magmin = magmin
        Snuffling.__init__(self)

    def setup(self):
        '''Customization of the snuffling.'''

        if self._magmin is None:
            self.set_name('Get GEOFON Events')
        else:
            self.set_name('Get GEOFON Events (> M %g)' % self._magmin)

    def call(self):
        '''Main work routine of the snuffling.'''

        # get time range visible in viewer
        viewer = self.get_viewer()
        tmin, tmax = viewer.get_time_range()

        # download event information from GEOFON web page
        # 1) get list of event names
        geofon = catalog.Geofon()
        event_names = geofon.get_event_names(
            time_range=(tmin,tmax),
            magmin=self._magmin)

        # 2) get event information and add a marker in the snuffler window
        for event_name in event_names:
            event = geofon.get_event(event_name)
            marker = EventMarker(event)
            self.add_markers([marker])

def __snufflings__():
    '''Returns a list of snufflings to be exported by this module.'''

    return [ GeofonEvents(),
             GeofonEvents(magmin=6),
             GeofonEvents(magmin=7),
             GeofonEvents(magmin=8) ]

How it works

Snuffler looks into the directory HOME/.snufflings for python scripts (*.py). Within each of these it tries to query the function __snufflings__() which should return a list of snuffling objects, which are instances of a snuffling class. A custom snuffling class is created by subclassing Snuffling. Within the derived class implement the methods setup() and call(). setup() is called during initialization of the snuffling object, call() is called when the user selects the menu entry. You may define several snuffling classes within one snuffling source file. You may also return several instances of a single snuffling class from the __snufflings__() function.

The Snuffling base class documentation can also be accessed with the command pydoc pyrocko.gui.snuffler.snuffling.Snuffling from the shell. Example snufflings can be found in src/gui/snuffler/snufflings/ in the pyrocko source code. More examples may be found in the contrib-snufflings repository repository.

More examples

How to add simple markers to the viewer

from pyrocko.gui.snuffler.snuffling import Snuffling
from pyrocko.gui.snuffler.pile_viewer import Marker

class Example1(Snuffling):

    '''Example Snuffling to demonstrate how to add markers to the viewer.

It looks at all selected traces and puts a Marker at the peak amplitude of the
raw traces. If no traces are selected all traces in view are used.  It is not
affected by filter settings of the viewer.

This works well for short continuous traces, but if longer or gappy traces are
in the viewer, there may be some problems which are not
'''

    def setup(self):
        # this sets the name for the menu entry:
        self.set_name('Example 1: mark peak amplitudes')

    def call(self):

        # remove all markers which have been previously added by this snuffling
        self.cleanup()

        # this is a shortcut to get selected traces or all traces in view
        for traces in self.chopper_selected_traces(fallback=True):

            for tr in traces:
                net, sta, loc, cha = tr.nslc_id

                # using a trace method to get time and amplitude
                time, amplitude = tr.absmax()

                # the marker kind sets the color of the marker
                kind = 3

                # create the marker object
                m = Marker([ (net, sta, loc, cha) ], time, time, kind )

                # add it to the viewer
                self.add_marker(m)

def __snufflings__():
    return [ Example1() ]