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 thersudp.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:
- 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:
- 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:
- 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:
- Returns:
Returns a data packet as an encoded bytes object.
- Raises:
IOError – if no socket is open (
rsudp.raspberryshake.openSOCK()
) prior to running this functionIOError – if the library is not initialized (
rsudp.raspberryshake.initRSlib()
) prior to running this function
- 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:
TR (int) – The transmission frequency (
rsudp.raspberryshake.getTR()
) in milliseconds between packetsDP (bytes) – The Raspberry Shake UDP data packet (
rsudp.raspberryshake.getDATA()
) calculate sample rate information from
- Return type:
- 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:
- 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:
- 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:
- 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:
- 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:
- 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:
- 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.
- 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 bothrsudp.raspberryshake.openSOCK()
andrsudp.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:
- 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:
- 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 byrsudp.raspberryshake.initRSlib()
, must be done beforersudp.raspberryshake.set_params()
.- Parameters:
host (str) – self-referential location at which to open a listening port (defaults to
''
which resolves to'localhost'
)- Raises:
IOError – if the library is not initialized (
rsudp.raspberryshake.initRSlib()
) prior to running this functionOSError – if the program cannot bind to the specified port number
- rsudp.raspberryshake.set_params()
Read a data packet off the port. Called by
rsudp.raspberryshake.initRSlib()
, must be done afterrsudp.raspberryshake.openSOCK()
but beforersudp.raspberryshake.getDATA()
. Will waitrsudp.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:
stream (obspy.core.stream.Stream) – The stream to update
d (bytes) – The Raspberry Shake UDP data packet (
rsudp.raspberryshake.getDATA()
) to parse Stream information from
- Return type:
- Returns:
A seismic data stream