Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
Initial commit
  • Loading branch information
jholmes authored Aug 3, 2016
1 parent 2cf292e commit ac4a93e
Show file tree
Hide file tree
Showing 6 changed files with 743 additions and 0 deletions.
29 changes: 29 additions & 0 deletions datalogger.props.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[connection]
port = /dev/ttyACM0
baudrate = 9600
timeout = 0.1

[data]
interval = 300

[device]
model = TC1
latitude = 32.865468
longitude = -117.253436
altitude = 11
network = IRI
station = SOCA
channel = BHZ
location = 00
samplerate = 18.78
dataquality = D

[file]
datapath = /srv/tc1/data/

[logging]
logpath = /srv/tc1/log/

[calibration]
samplelimit = 405648
offset = 34432
117 changes: 117 additions & 0 deletions seisCalibration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import serial, sys, time, os.path, datetime
from time import strftime
import numpy as np
import ConfigParser as cp

def printStats(alldata, alladj, counts, etime):
numsam = len(alldata)
(numpos, numneg, numzer) = counts
pospct = (numpos/(numsam-numzer))*100
negpct = (numneg/(numsam-numzer))*100
zerpct = (numzer/numsam)*100
print("\n-----------------------------------------------------------------------------")
print "Running time seconds: %d" % etime
print "# of samples: %d" % numsam
print " Max/Adjusted max: %d / %d" % (np.amax(alldata),np.amax(alladj))
print " Min/Adjusted min: %d / %d" % (np.amin(alldata),np.amin(alladj))
print " Avg/Adjusted avg: %d / %d" % (np.mean(alldata),np.mean(alladj))
print " # of positive: %d (%.2f%%)" % (numpos,pospct)
print " # of negative: %d (%.2f%%)" % (numneg,negpct)
print " # of zeroes: %d (%.2f%%)" % (numzer,zerpct)
print "System check completed."

def msg(txt):
sys.stdout.write(txt)
sys.stdout.flush()

def main():
# Check if the data logger is running. If so, stop.
# We can't risk locking out the serial port from the data logger.

if os.path.exists('/srv/tc1/run/seis_data_logger.pid'):
print "Error: Data Logger is already running! Exiting..."
exit(0)

alldata = []
alladj = []
numpos = 0
numneg = 0
numzer = 0

config = cp.RawConfigParser()
config.read("/srv/tc1/conf/datalogger.props.cfg")

port = config.get ("connection", "port")
baud = config.getint ("connection", "baudrate")
tout = config.getfloat("connection", "timeout")
offset = config.getint ("calibration","offset")
limit = config.getint ("calibration","samplelimit")
model = config.get ("device", "model")
srate = config.getfloat("device", "samplerate")

ttlsec = limit / srate
m, s = divmod(ttlsec, 60)
h, m = divmod(m, 60)
now = datetime.datetime.now()
ftime = now + datetime.timedelta(hours=h, minutes=m, seconds=s)
(fhr,fmn,fsc) = (ftime.time().hour,ftime.time().minute,ftime.time().second)

print("SIO Seismic Calibration Tool, v1.0")
print("* Initialized on " + strftime('%x at %X %Z'))
print("* Device info: model %s on %s (%d Hz transmission rate)" % (model, port, baud))
print("* Using offset: %d" % offset)
print("* Sample limit: %d (approx. %d:%02d:%02d, finish at %d:%02d:%02d)" % (limit,h,m,s,fhr,fmn,fsc))
print("-----------------------------------------------------------------------------")
print(" Sample Count | Sample Rate | Original Value | Adjusted Value | Current Mean ")

device = serial.Serial(port,baud,timeout=tout)
stime = time.time()
try:
sampcount = 0
runcount = 0
curtotl = 0
while len(alldata) < limit:
sproctime = time.time()
data = device.readline()[:-2]
sampcount = sampcount + 1
if data:
eproctime = time.time()

try:
rawdata = int(data)
runcount = runcount + 1
alldata.append(rawdata)
adjdata = rawdata - offset
alladj.append(adjdata)
curtotl = curtotl + rawdata
curmean = int(curtotl / runcount)
if adjdata > 0:
numpos = numpos + 1
elif adjdata < 0:
numneg = numneg + 1
else:
numzer = numzer + 1

samprate = sampcount / (eproctime - sproctime)

m = "{3:^13d} | {2:^11.2f} | {1:^14d} | {0:^14d} | {4:^14d}".format(adjdata,rawdata,samprate,runcount,curmean)
msg(m + chr(13))
except ValueError:
continue
sampcount = 0
except KeyboardInterrupt:
etime = time.time()
elapsed = etime - stime
counts = (float(numpos),float(numneg),float(numzer))
printStats(alldata, alladj, counts, elapsed)
exit()
etime = time.time()
elapsed = etime - stime
counts = (float(numpos),float(numneg),float(numzer))
printStats(alldata, alladj, counts, elapsed)

if __name__ == '__main__':
main()
135 changes: 135 additions & 0 deletions seisDataLogger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# seisDataLogger.py
#
# Connects to educational seismometer and gathers data.
# Make save to current trace every user-defined interval of seconds
# Reads a config file for parameters, but runs as a process.
#

from obspy.core import Stream, Trace, UTCDateTime
from seisDataLoggerDaemon import Daemon
from threading import Thread
from time import strftime
import serial, sys, os
import numpy as np


class DataLoggerDaemon(Daemon):
def run(self):
baseTime = UTCDateTime()

# Assign all the configuration variables
port = self.config.get ("connection","port")
baud = self.config.getint ("connection","baudrate")
tout = self.config.getfloat("connection","timeout")
interval = self.config.getint ("data","interval")
offset = self.config.getint ("calibration","offset")
network = self.config.get ("device","network")
station = self.config.get ("device","station")
location = self.config.get ("device","location")
channel = self.config.get ("device","channel")
samprate = self.config.getfloat("device","samplerate")
dataqual = self.config.get ("device","dataquality")

sampleIdx = 0
traceData = np.array([])

self.logger.debug("["+ strftime('%X') + "] connecting...")

rawData = serial.Serial(port,baud,timeout=tout)

self.logger.debug("["+ strftime('%X') + "] listening for incoming data...")

while True: # While loop that loops forever
while (rawData.inWaiting()==0): #Wait here until there is data
pass #do nothing

dataPointString = rawData.readline()

try:
traceData = np.append(traceData, int(dataPointString))
except ValueError:
offset = int(np.mean(traceData))
self.logger.debug("["+ strftime('%X') + "] * Bad value received. Replacing with current mean...")
traceData = np.append(traceData, offset)

sampleIdx = sampleIdx + 1

currentTime = UTCDateTime()
elapsedTime = (currentTime - baseTime)

# Write the data after x seconds
if elapsedTime >= (interval + (baseTime.microsecond / 1e6)):
# Fill header attributes
stats = {'network': network,
'station': station,
'location': location,
'channel': channel,
'npts': len(traceData),
'sampling_rate': samprate,
'mseed': {'dataquality': dataqual},
'starttime': baseTime}

# Save the file using a different thread.
worker = Thread(target=self._writeData, args=(traceData, stats, baseTime))
worker.setDaemon(True)
worker.start()

baseTime = currentTime

sampleIdx = 0

traceData = np.array([])

def _writeData(self, traceData, stats, timeObj):
streamObj = Stream([Trace(data=traceData, header=stats)])

filename = self._prepareFilename(timeObj)
offset = int(np.mean(streamObj.traces[0].data))
streamObj.traces[0].data = np.array([x - offset for x in streamObj.traces[0].data])

self.logger.debug("["+ strftime('%X') + "] Saving %d samples (corrected by %d) to %s..." % (len(traceData), offset, filename))
streamObj.write(filename, format='MSEED')

def _prepareFilename(self, timeObj):
datapath = self.config.get("file","datapath")
filepath = datapath +"%d/%d/" % (timeObj.year, timeObj.julday)

try:
if not os.path.exists(filepath):
os.makedirs(filepath)
except OSError as exception:
self.logger.debug("["+ strftime('%X') + "] * Error preparing path: (%d) %s" % (exception.errno, exception.strerror))

network = self.config.get("device","network")
station = self.config.get("device","station")
channel = self.config.get("device","channel")
filename = network+"."+station+".%02d%02d%4d_%02d%02d%02d." % \
(timeObj.day,timeObj.month,timeObj.year,
timeObj.hour,timeObj.minute,timeObj.second) +channel+".mseed"
return (filepath+filename)

def normalize(v):
norm=np.linalg.norm(v)
if norm==0:
return v
return v/norm

if __name__ == "__main__":
daemon = DataLoggerDaemon('/srv/tc1/run/seis_data_logger.pid')
if len(sys.argv) == 2:
if 'start' == sys.argv[1]:
daemon.start()
elif 'stop' == sys.argv[1]:
daemon.stop()
elif 'restart' == sys.argv[1]:
daemon.restart()
else:
print "Unknown command"
sys.exit(2)
sys.exit(0)
else:
print "usage: %s start|stop|restart" % sys.argv[0]
sys.exit(2)
Loading

0 comments on commit ac4a93e

Please sign in to comment.