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.231.10')

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 ↑