build.rsudp.packetize.get_samps()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 21
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.2559

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 21
ccs 3
cts 5
cp 0.6
rs 10
c 0
b 0
f 0
cc 2
nop 1
crap 2.2559
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()