You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

365 lines
11 KiB
Python

from __future__ import print_function
from .lineType import Nw, Sg, Sr, Sl, Sa, Na, Dl, Se, Ff, Pz, Ia, Cl
from .nodesi import Instruments
from .nodesnslc import Network, StationGroup, DontFit
import seiscomp.datamodel, seiscomp.io, seiscomp.client
from .stationResolver import StationResolver
import sys
import os
import glob
import re
__VERSION__ = "0.1"
class Tab(object):
def version(self):
return __VERSION__
def __init__(self, instrumentPrefix = None, defaultsFile = None, filterFolder = None, xmlFolder = None, database = None):
self.i = Instruments(instrumentPrefix)
self.n = {}
self.g = {}
self.sas = []
self.nas = []
self.ias = []
self.stationResolver = StationResolver()
self._filterFolder = None
print("Starting tab2inv version %s" % self.version(), file=sys.stderr)
if not filterFolder:
print(" Warning, not filter folder supplied.", file=sys.stderr)
else:
if not os.path.isdir(filterFolder):
raise Exception("Filter folder does not exist.")
self._filterFolder = filterFolder
if defaultsFile is not None:
self._defaults(defaultsFile)
if database is not None:
self._loadDatabase(database)
if xmlFolder is not None:
self._loadXml(xmlFolder)
def _defaults(self, filename):
sas = []
ias = []
nas = []
try:
fd = open(filename)
print(" Parsing defaults file: %s" % (filename), file=sys.stderr)
for line in fd:
line = line.strip()
if not line or line[0] == "#": continue
(Type, Content) = line.split(":",1)
if Type == "Nw":
raise Exception("Defaults file can only contain attributes")
elif Type == "Na":
nas.append(Na(Content))
elif Type == "Sa":
sas.append(Sa(Content))
elif Type == "Sl":
raise Exception("Defaults file can only contain attributes")
elif Type == "Ia":
ias.append(Ia(Content))
elif Type == "Se":
raise Exception("Defaults file can only contain attributes")
elif Type == "Dl":
raise Exception("Defaults file can only contain attributes")
elif Type == "Cl":
raise Exception("Defaults file can only contain attributes")
elif Type == "Ff":
raise Exception("Defaults file can only contain attributes")
elif Type == "If":
raise Exception("Defaults file can only contain attributes")
elif Type == "Pz":
raise Exception("Defaults file can only contain attributes")
else:
print(" Ignored line", line, file=sys.stderr)
fd.close()
except Exception as e:
print(" Warning: %s" % e, file=sys.stderr)
pass
self.sas = sas
self.nas = nas
self.ias = ias
def _loadDatabase(self, dbUrl):
m = re.match("(?P<dbDriverName>^.*):\/\/(?P<dbAddress>.+?:.+?@.+?\/.+$)", dbUrl)
if not m:
raise Exception("error in parsing SC3 DB url")
db = m.groupdict()
try:
registry = seiscomp.system.PluginRegistry.Instance()
registry.addPluginName("dbmysql")
registry.loadPlugins()
except Exception as e:
raise #"Cannot load database driver: %s"
dbDriver = seiscomp.io.DatabaseInterface.Create(db["dbDriverName"])
if dbDriver is None:
raise Exception("Cannot find database driver " + db["dbDriverName"])
if not dbDriver.connect(db["dbAddress"]):
raise Exception("Cannot connect to database at " + db["dbAddress"])
dbQuery = seiscomp.datamodel.DatabaseQuery(dbDriver)
if dbQuery is None:
raise Exception("Cannot get DB query object")
print(" Loading inventory from database ... ", end=' ', file=sys.stderr)
inventory = seiscomp.datamodel.Inventory()
dbQuery.loadNetworks(inventory)
for ni in range(inventory.networkCount()):
dbQuery.loadStations(inventory.network(ni))
print("Done.", file=sys.stderr)
if inventory:
self.stationResolver.collectStations(inventory, True)
def _loadXml(self, folder):
print(" Loading inventory from XML file ... ", end=' ', file=sys.stderr)
for f in glob.glob(os.path.join(folder, "*.xml")):
ar = seiscomp.io.XMLArchive()
ar.open(f)
inventory = seiscomp.datamodel.Inventory_Cast(ar.readObject())
ar.close()
if inventory:
self.stationResolver.collectStations(inventory)
print("Done.", file=sys.stderr)
def digest(self, tabFilename):
sas = []
ias = []
nw = None
n = None
g = None
print(" Parsing file: %s" % (tabFilename), file=sys.stderr)
if not tabFilename or not os.path.isfile(tabFilename):
raise Exception("Supplied filename is invalid.")
if tabFilename in list(self.n.keys()) or tabFilename in list(self.g.keys()):
raise Exception("File %s is already digested." % tabFilename)
filename = 1
try:
fd = open(tabFilename)
for line in fd:
obj = None
line = line.strip()
if not line or line[0] == "#": continue
if str(line).find(":") == -1:
raise Exception("Invalid line format '%s'" % line)
(Type, Content) = line.split(":",1)
if Type == "Nw":
if n or g:
raise Exception("Network or Station Group already defined, only one Hr line should be defined per file.")
try:
nw = Nw(Content)
except Exception as e:
raise Exception("Error while creating nw from '%s': %s" % (Content, e))
try:
for na in self.nas: nw.Na(na) # Defaults
except Exception as e:
raise Exception("Error while loading (defaults) %s into %s: %s" % (na, nw, e))
elif Type == "Sg":
if n or g:
raise Exception("Network or Station Group already defined, only one Hr line should be defined per file.")
try:
sg = Sg(Content)
except Exception as e:
raise Exception("Error while creating sg from '%s': %s" % (Content, e))
try:
for na in self.nas: sg.Na(na) # Defaults
except Exception as e:
raise Exception("Error while loading (defaults) %s into %s: %s" % (na, sg, e))
elif Type == "Na":
if not nw and not sg:
raise Exception("No network defined, no Na line before a Hr line.")
if n or g:
raise Exception("No Na lines after a Sl line. Network has already been defined.")
try:
na = Na(Content)
except Exception as e:
raise Exception("Error while creating na from '%s': %s" % (Content, e))
if nw:
try:
nw.Na(na)
except Exception as e:
raise Exception("Error while adding %s to %s: %s" % (na, nw, e))
else:
try:
sg.Na(na)
except Exception as e:
raise Exception("Error while adding %s to %s: %s" % (na, sg, e))
elif Type == "Sa":
if not nw:
raise Exception("Not Sa line before a hr line allowed.")
try:
sas.append(Sa(Content))
except Exception as e:
raise Exception("Error while creating Sa from '%s': %s" % (Content,e))
elif Type == "Sl":
if not n:
if not nw:
raise Exception("No network defined, Hr line should come before station line.")
else:
n = Network(nw)
for (filename, network) in self.n.items():
if network.conflict(n):
raise Exception("Network already defined %s (%s)-(%s) by file %s." % (network.code, network.start, network.end, filename))
try:
sl = Sl(Content)
except Exception as e:
raise Exception("Error while creating sl from '%s': %s" % (Content, e))
# Fill in attributes
try:
for sa in self.sas: sl.Sa(sa) # Defaults
except Exception as e:
raise Exception("Error while loading (default) %s into %s: %s" % (sa, sl, e))
try:
for sa in sas: sl.Sa(sa) # Collected
except Exception as e:
raise Exception("Error while loading %s into %s: %s" % (str(sa), str(sl), e))
# Digest by Station
try:
n.Sl(sl)
except DontFit:
raise Exception("%s does not fit in %s" % (sl, n))
except Exception as e:
raise Exception("Error while loading %s into %s: %s" % (sl, n, e))
elif Type == "Sr":
if not g:
if not sg:
raise Exception("No station group defined, Sg line should come before station reference line.")
else:
g = StationGroup(sg)
for (filename, stationGroup) in self.g.items():
if stationGroup.conflict(g):
raise Exception("Station group already defined %s (%s)-(%s) by file %s." % (stationGroup.code, stationGroup.start, stationGroup.end, filename))
for (filename, network) in self.n.items():
if network.conflict(g):
raise Exception("Station group conflict network already defined %s (%s)-(%s) by file %s." % (network.code, network.start, network.end, filename))
try:
sr = Sr(Content)
except Exception as e:
raise Exception("Error while creating sr from '%s': %s" % (Content, e))
# Digest by Station Reference
try:
g.Sr(sr)
except DontFit:
raise Exception("%s does not fit in %s" % (sr, n))
except Exception as e:
raise Exception("Error while loading %s into %s: %s" % (sr, n, e))
elif Type == "Ia":
ias.append(Ia(Content))
elif Type == "Se":
obj = Se(Content)
elif Type == "Dl":
obj = Dl(Content)
elif Type == "Cl":
obj = Cl(Content)
elif Type == "Ff":
obj = Ff(self._filterFolder, Content)
elif Type == "If":
obj = Pz(Content,'D')
elif Type == "Pz":
obj = Pz(Content,'A')
else:
print(" Ignored line", line, file=sys.stderr)
## Process Instrument
if obj:
try:
for ia in self.ias: obj.Ia(ia) # Defaults
except Exception as e:
raise Exception("Error while loading (defaults) %s into %s: %s" % (ia, obj, e))
try:
for ia in ias: obj.Ia(ia) # Collected
except Exception as e:
raise Exception("Error while loading %s into %s: %s" % (ia, obj, e))
try:
self.i.add(obj)
except Exception as e:
raise Exception("Error while loading %s into Instruments db: %s" % (obj, e))
obj = None
# Process Network
if n:
self.n[tabFilename] = n
# Process Station Group
if g:
self.g[tabFilename] = g
except Exception as e:
raise e
finally:
if fd:
fd.close()
def check(self):
# Instrument alone check
if self.i.keys:
print("\nCheking Instruments Loaded:\n", file=sys.stderr)
error = self.i.check(self.n)
if error:
for e in error: print(e, file=sys.stderr)
else:
print("\nNo instruments loaded", file=sys.stderr)
# Cross Check
error = []
if self.n:
print("\nChecking Networks Loaded:\n", file=sys.stderr)
for network in self.n.values():
error.extend(network.check(self.i))
if error:
for e in error: print(e, file=sys.stderr)
else:
print("\nNo network/stations loaded.", file=sys.stderr)
def sc3Obj(self, sc3i = None):
if not sc3i:
sc3i = seiscomp.datamodel.Inventory()
for network in list(self.n.values()):
sc3n = network.sc3Obj(self.i)
sc3i.add(sc3n)
for sc3o in self.i.sc3Objs():
sc3i.add(sc3o)
self.stationResolver.collectStations(sc3i)
for stationGroup in list(self.g.values()):
sc3g = stationGroup.sc3Obj(self.stationResolver)
sc3i.add(sc3g)
return sc3i