build.rsudp.packetize   A
last analyzed

Complexity

Total Complexity 18

Size/Duplication

Total Lines 115
Duplicated Lines 0 %

Test Coverage

Coverage 73.58%

Importance

Changes 0
Metric Value
wmc 18
eloc 61
dl 0
loc 115
ccs 39
cts 53
cp 0.7358
rs 10
c 0
b 0
f 0

4 Functions

Rating   Name   Duplication   Size   Complexity  
B main() 0 19 6
A get_samps() 0 21 2
A cutoff_calc() 0 17 3
B packetize() 0 32 7
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3 1
import os, sys
4 1
import getopt
5 1
from obspy import read
6 1
from datetime import timedelta
7 1
from rsudp.test import TEST
8 1
from rsudp.helpers import lesser_multiple
9
10
11 1
SMP = {
12
	0.01: 25,
13
	0.02: 50,
14
}
15
16
17 1
def get_samps(stream):
18
	'''
19
	Return the number of samples to place in each packet.
20
	This number is based on the sampling frequency of the data in question.
21
22
	Raspberry Shake data is sent to the UDP port either in packets of 25
23
	(for sampling frequency of 100 Hz) or 50 (for frequency of 50 Hz).
24
25
	This is hardcoded and will not change for the foreseeable future,
26
	which means that it can be used to determine the variety of sensor used
27
	(50 Hz is the original versions of RS1D).
28
29
	:param obspy.core.stream.Stream stream: Stream object to calculate samples per packet for
30
31
	:rtype: int
32
	:return: the number of samples per packet (either 25 or 50)
33
	'''
34 1
	try:
35 1
		return SMP[stream[0].stats.delta]
36
	except KeyError as e:
37
		raise KeyError('Sampling frequency of %s is not supported. Is this Raspberry Shake data?' % (e))
38
39
40 1
def cutoff_calc(stream):
41
	'''
42
	Return the number of samples that will be transcribed to UDP packet formatted ascii text.
43
	Iterates over each trace in the stream to make this calculation.
44
45
	:param obspy.core.stream.Stream stream: Stream object to calculate number of samples from
46
47
	:rtype: int, int
48
	:return: 1) the number of samples to transcribe, 2) the number of samples in each packet
49
	'''
50 1
	samps = get_samps(stream)
51 1
	c = lesser_multiple(len(stream[0].data), base=samps)
52 1
	for t in stream:
53 1
		n = lesser_multiple(len(t.data), base=samps)
54 1
		if n < c:
55
			c = n
56 1
	return c, samps
57
58
59 1
def packetize(inf, outf, testing=False):
60
	'''
61
	Reads a seismic data file and converts it to ascii text.
62
63
	:param str inf: the input data file to convert
64
	:param str outf: where to write the output file
65
	'''
66 1
	if os.path.isfile(os.path.expanduser(inf)):
67 1
		stream = read(inf)
68 1
		cutoff, samps = cutoff_calc(stream)
69 1
		n = 0
70 1
		time = stream[0].stats.starttime
71
72 1
		with open(outf, 'w') as f:
73 1
			for i in range(0, int(cutoff/samps)):
74 1
				ptime = time + timedelta(seconds=stream[0].stats.delta*n)
75 1
				for t in stream:
76 1
					data = ''
77 1
					chan = t.stats.channel
78 1
					for j in range(n, n+samps):
79 1
						data += ', %s' % t.data[j]
80 1
					line = "{'%s', %.3f%s}%s" % (chan, ptime.timestamp, data, os.linesep)
81 1
					f.write(line)
82 1
				n += samps
83
84 1
			f.write('TERM%s' % (os.linesep))
85
86 1
		print('Data written to %s' % outf)
87 1
		if testing:
88 1
			TEST['x_packetize'][1] = True
89
	else:
90
		print('Input file does not exist: %s' % inf)
91
92
93 1
def main():
94
	'''
95
	This function reads command line arguments, then calls
96
	:py:func:`rsudp.packetize.packetize` with those arguments.
97
	'''
98
	inf, outf = False, False
99
	opts = getopt.getopt(sys.argv[1:], 'i:o:',
100
			['in=', 'out=',]
101
			)[0]
102
103
	for opt, arg in opts:
104
		if opt in ('-i', '--in='):
105
			inf = arg
106
		if opt in ('-o', '--out='):
107
			outf = arg
108
	if inf and outf:
109
		packetize(inf=inf, outf=outf)
110
	else:
111
		print('Usage: packetize.py -i infile.ms -o testdata')
112
113
if __name__ == '__main__':
114
	main()