rsudp.raspberryshake (main library)

Note

If you are starting this program from a command line by using rs-client or a start script, the functions in this library will be executed by the rsudp.client automatically. See Running rsudp for details.

If you are a developer looking for helper functions to create a new module, you have come to the right place.

This is the main library powering rsudp. It contains common functions to open a port listener, get data packets, parse the information in those packets, and help consumer modules update their data streams.

Prior to working with data from the port, this library must be initialized using rsudp.raspberryshake.initRSlib():

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R940D')

Note

This request will time out if there is no data being sent to the port.

After initializing the library, the rsudp.raspberryshake.getDATA() function and its derivatives will be available for use.

class rsudp.raspberryshake.ConsumerThread

The default consumer thread setup. Import this consumer and easily create your own consumer modules! This class modifies the threading.Thread object to include some settings that all rsudp consumers need, some of which the rsudp.p_producer.Producer needs in order to function.

Currently, the modifications that this module makes to threading.Thread objects are:

self.sender = 'ConsumerThread'  # module name used in logging
self.alarm = False              # the Producer reads this to set the ``ALARM`` state
self.alarm_reset = False        # the Producer reads this to set the ``RESET`` state
self.alive = True               # this is used to keep the main ``for`` loop running

For more information on creating your own consumer threads, see Adding your own consumer modules.

rsudp.raspberryshake.copy(orig)

True-copy a stream by creating a new stream and copying old attributes to it. This is necessary because the old stream accumulates something that causes CPU usage to increase over time as more data is added. This is a bug in obspy that I intend to find–or at the very least report–but until then this hack works fine and is plenty fast enough.

In this example, we make a stream object with some RS 1Dv7 data and then copy it to a new stream:

>>> import rsudp.raspberryshake as rs
>>> from obspy.core.stream import Stream
>>> rs.initRSlib(dport=8888, rsstn='R3BCF')
>>> s = Stream()
>>> d = rs.getDATA()
>>> t = rs.make_trace(d)
>>> s = rs.update_stream(s, d)
>>> s
1 Trace(s) in Stream:
AM.R3BCF.00.EHZ | 2020-02-21T19:58:50.292000Z - 2020-02-21T19:58:50.532000Z | 100.0 Hz, 25 samples
>>> s = rs.copy(s)
>>> s
1 Trace(s) in Stream:
AM.R3BCF.00.EHZ | 2020-02-21T19:58:50.292000Z - 2020-02-21T19:58:50.532000Z | 100.0 Hz, 25 samples
Parameters

orig (obspy.core.stream.Stream) – The data stream to copy information from

Return type

obspy.core.stream.Stream

Returns

A low-memory copy of the passed data stream

rsudp.raspberryshake.getCHN(DP)

Extract the channel information from the data packet. Requires rsudp.raspberryshake.getDATA() packet as argument.

In this example, we get the channel code from a Shake 1Dv7 data packet:

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R3BCF')
>>> d = rs.getDATA()
>>> rs.getCHN(d)
'EHZ'
Parameters

DP (bytes) – The Raspberry Shake UDP data packet (rsudp.raspberryshake.getDATA()) to parse channel information from

Return type

str

Returns

Returns the instrument channel as a string.

rsudp.raspberryshake.getCHNS()

Get a list of channels sent to the port.

In this example, we list channels from a Boom:

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R940D')
>>> rs.getCHNS()
['EHZ', 'HDF']
Return type

list

Returns

The list of channels being sent to the port (from the single IP address sending data)

rsudp.raspberryshake.getDATA()

Read a data packet off the port.

In this example, we get a Shake 1Dv7 data packet:

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R3BCF')
>>> d = rs.getDATA()
>>> d
b"{'EHZ', 1582315130.292, 14168, 14927, 16112, 17537, 18052, 17477,
15418, 13716, 15604, 17825, 19637, 20985, 17325, 10439, 11510, 17678,
20027, 20207, 18481, 15916, 13836, 13073, 14462, 17628, 19388}"
Return type

bytes

Returns

Returns a data packet as an encoded bytes object.

Raises
rsudp.raspberryshake.getSR(TR, DP)

Get the sample rate in samples per second. Requires an integer transmission frequency and a data packet as arguments.

In this example, we calculate the number of samples per second from a Shake 1Dv7:

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R3BCF')
>>> d = rs.getDATA()
>>> tr = rs.getTR(rs.getCHN(d))
>>> tr
250
>>> sps = rs.getSR(tr, d)
>>> sps
100
Parameters
Return type

int

Returns

The sample rate in samples per second from a specific channel

rsudp.raspberryshake.getSTREAM(DP)

Get the samples in a data packet as a list object. Requires rsudp.raspberryshake.getDATA() packet as argument.

In this example, we get a list of samples from a Shake 1Dv7 data packet:

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R3BCF')
>>> d = rs.getDATA()
>>> s = rs.getSTREAM(d)
>>> s
[14168, 14927, 16112, 17537, 18052, 17477, 15418, 13716, 15604,
 17825, 19637, 20985, 17325, 10439, 11510, 17678, 20027, 20207,
 18481, 15916, 13836, 13073, 14462, 17628, 19388]
Parameters

DP (bytes) – The Raspberry Shake UDP data packet (rsudp.raspberryshake.getDATA()) to parse stream information from

Return type

list

Returns

List of data samples in the packet

rsudp.raspberryshake.getTIME(DP)

Extract the timestamp from the data packet. Timestamp is seconds since 1970-01-01 00:00:00Z, which can be passed directly to an obspy.core.utcdatetime.UTCDateTime object:

In this example, we get the timestamp of a Shake 1Dv7 data packet and convert it to a UTCDateTime:

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R3BCF')
>>> from obspy import UTCDateTime
>>> d = rs.getDATA()
>>> t = rs.getTIME(d)
>>> t
1582315130.292
>>> dt = obspy.UTCDateTime(t, precision=3)
>>> dt
UTCDateTime(2020, 2, 21, 19, 58, 50, 292000)
Parameters

DP (bytes) – The Raspberry Shake UDP data packet (rsudp.raspberryshake.getDATA()) to parse time information from

Return type

float

Returns

Timestamp in decimal seconds since 1970-01-01 00:00:00Z

rsudp.raspberryshake.getTR(chn)

Get the transmission rate in milliseconds between consecutive packets from the same channel. Must wait to receive a second packet from the same channel. Requires a rsudp.raspberryshake.getCHN() or a channel name string as argument.

In this example, we calculate the transmission frequency of a Shake 1Dv7:

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R3BCF')
>>> d = rs.getDATA()
>>> tr = rs.getTR(rs.getCHN(d))
>>> tr
250
Parameters

chn (str) – The seismic instrument channel (rsudp.raspberryshake.getCHN()) to calculate transmission rate information from

Return type

int

Returns

Transmission rate in milliseconds between consecutive packets from a specific channel

rsudp.raspberryshake.getTTLCHN()

Calculate total number of channels received, by counting the number of channels returned by rsudp.raspberryshake.getCHNS().

In this example, we get the number of channels from a Shake & Boom:

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R940D')
>>> rs.getTTLCHN()
2
Return type

int

Returns

The number of channels being sent to the port (from the single IP address sending data)

rsudp.raspberryshake.get_inventory(sender='get_inventory')

Downloads the station inventory from the Raspberry Shake FDSN and stores it as an obspy.core.inventory.inventory.Inventory object which is available globally.

In this example, we get the R940D station inventory from the Raspberry Shake FDSN:

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R940D')
>>> inv = rs.get_inventory()
>>> print(inv)
Inventory created at 2020-02-21T20:37:34.246777Z
        Sending institution: SeisComP3 (gempa testbed)
        Contains:
                Networks (1):
                        AM
                Stations (1):
                        AM.R940D (Raspberry Shake Citizen Science Station)
                Channels (2):
                        AM.R940D.00.EHZ, AM.R940D.00.HDF
Parameters

sender(optional) The name of the function calling the rsudp.printM() logging function

Return type

obspy.core.inventory.inventory.Inventory or bool

Returns

The inventory of the Raspberry Shake station in the rsudp.raspberryshake.stn variable.

rsudp.raspberryshake.get_ip()

Return a reliable network IP to report to the user when there is no data received. This helps the user set their Raspberry Shake’s datacast streams to point to the correct location if the library raises a “no data received” error. Solution adapted from this stackoverflow answer.

>>> get_ip()
'192.168.1.23'
Return type

str

Returns

The network IP of the machine that this program is running on

rsudp.raspberryshake.handler(signum, frame, ip='192.168.220.20')

The signal handler for the nodata alarm.

Parameters
  • signum (int) – signal number

  • frame (int) – frame number

  • ip (str) – the IP of the box this program is running on (i.e. the device the Raspberry Shake should send data to)

Raises

IOError – on UNIX systems if no data is received

rsudp.raspberryshake.initRSlib(dport=8888, rsstn='Z0000', timeout=10)

Initializes this library (rsudp.raspberryshake()). Set values for data port, station, network, and port timeout prior to opening the socket. Calls both rsudp.raspberryshake.openSOCK() and rsudp.raspberryshake.set_params().

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R3BCF')

The library is now initialized:

>>> rs.initd
True
Parameters
  • dport (int) – The local port the Raspberry Shake is sending UDP data packets to. Defaults to 8888.

  • rsstn (str) – The name of the station (something like ‘RCB43’ or ‘S0CDE’)

  • timeout (int) – The number of seconds for rsudp.raspberryshake.set_params() to wait for data before an error is raised (zero for unlimited wait)

Return type

str

Returns

The instrument channel as a string

rsudp.raspberryshake.make_trace(d)

Makes a trace and assigns it some values using a data packet.

In this example, we make a trace object with some RS 1Dv7 data:

>>> import rsudp.raspberryshake as rs
>>> rs.initRSlib(dport=8888, rsstn='R3BCF')
>>> d = rs.getDATA()
>>> t = rs.make_trace(d)
>>> print(t)
AM.R3BCF.00.EHZ | 2020-02-21T19:58:50.292000Z - 2020-02-21T19:58:50.532000Z | 100.0 Hz, 25 samples
Parameters

d (bytes) – The Raspberry Shake UDP data packet (rsudp.raspberryshake.getDATA()) to parse Trace information from

Return type

obspy.core.trace.Trace

Returns

A fully formed Trace object to build a Stream with

rsudp.raspberryshake.openSOCK(host='')

Initialize a socket at the port specified by rsudp.raspberryshake.port. Called by rsudp.raspberryshake.initRSlib(), must be done before rsudp.raspberryshake.set_params().

Parameters

host (str) – self-referential location at which to open a listening port (defaults to ‘’ which resolves to ‘localhost’)

Raises
rsudp.raspberryshake.set_params()

Read a data packet off the port. Called by rsudp.raspberryshake.initRSlib(), must be done after rsudp.raspberryshake.openSOCK() but before rsudp.raspberryshake.getDATA(). Will wait rsudp.raspberryshake.to seconds for data before raising a no data exception (only available with UNIX socket types).

rsudp.raspberryshake.update_stream(stream, d, **kwargs)

Returns an updated Stream object with new data, merged down to one trace per available channel. Most sub-consumers call this each time they receive data packets in order to keep their obspy stream current.

In this example, we make a stream object with some RS 1Dv7 data:

>>> import rsudp.raspberryshake as rs
>>> from obspy.core.stream import Stream
>>> rs.initRSlib(dport=8888, rsstn='R3BCF')
>>> s = Stream()
>>> d = rs.getDATA()
>>> t = rs.make_trace(d)
>>> s = rs.update_stream(s, d)
>>> print(s)
1 Trace(s) in Stream:
AM.R3BCF.00.EHZ | 2020-02-21T19:58:50.292000Z - 2020-02-21T19:58:50.532000Z | 100.0 Hz, 25 samples
Parameters
Return type

obspy.core.stream.Stream

Returns

A seismic data stream


Back to top ↑