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.
1038 lines
31 KiB
Python
1038 lines
31 KiB
Python
#*****************************************************************************
|
|
# inventory.py
|
|
#
|
|
# XML I/O for Inventory (new schema)
|
|
#
|
|
# (c) 2006 Andres Heinloo, GFZ Potsdam
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify it
|
|
# under the terms of the GNU General Public License as published by the
|
|
# Free Software Foundation; either version 2, or (at your option) any later
|
|
# version. For more information, see http://www.gnu.org/
|
|
#*****************************************************************************
|
|
|
|
from __future__ import (absolute_import, division, print_function,
|
|
unicode_literals)
|
|
|
|
import seiscomp.legacy.db.xmlio.xmlwrap as _xmlwrap
|
|
from seiscomp.legacy.db import DBError
|
|
|
|
try:
|
|
from xml.etree import cElementTree as ET # Python 2.5?
|
|
except ImportError:
|
|
import cElementTree as ET
|
|
|
|
_root_tag = "{http://geofon.gfz-potsdam.de/ns/Inventory/1.0/}inventory"
|
|
|
|
class _UsedSensor(object):
|
|
def __init__(self):
|
|
self.calibration = set()
|
|
|
|
def reg_calibration(self, id):
|
|
self.calibration.add(id)
|
|
|
|
class _UsedDatalogger(object):
|
|
def __init__(self):
|
|
self.decimation = set()
|
|
self.calibration = set()
|
|
|
|
def reg_decimation(self, sampleRateNumerator, sampleRateDenominator):
|
|
self.decimation.add((sampleRateNumerator, sampleRateDenominator))
|
|
|
|
def reg_calibration(self, id):
|
|
self.calibration.add(id)
|
|
|
|
class _UsedAuxilliaryDevice(object):
|
|
def __init__(self):
|
|
self.source = set()
|
|
|
|
def reg_source(self, id):
|
|
self.source.add(id)
|
|
|
|
class _UsedInstruments(object):
|
|
def __init__(self):
|
|
self.sensor = {}
|
|
self.datalogger = {}
|
|
self.auxDevice = {}
|
|
|
|
def reg_sensor(self, name):
|
|
try:
|
|
return self.sensor[name]
|
|
|
|
except KeyError:
|
|
obj = _UsedSensor()
|
|
self.sensor[name] = obj
|
|
return obj
|
|
|
|
def reg_datalogger(self, name):
|
|
try:
|
|
return self.datalogger[name]
|
|
|
|
except KeyError:
|
|
obj = _UsedDatalogger()
|
|
self.datalogger[name] = obj
|
|
return obj
|
|
|
|
def reg_auxDevice(self, name):
|
|
try:
|
|
return self.auxDevice[name]
|
|
|
|
except KeyError:
|
|
obj = _UsedAuxilliaryDevice()
|
|
self.auxDevice[name] = obj
|
|
return obj
|
|
|
|
class _UsedFilters(object):
|
|
def __init__(self):
|
|
self.filters = set()
|
|
|
|
def reg_filter(self, name):
|
|
self.filters.add(name)
|
|
|
|
|
|
#*****************************************************************************
|
|
# XML IN (instruments)
|
|
#*****************************************************************************
|
|
|
|
def _responseFIR_in(xresponseFIR, inventory):
|
|
if xresponseFIR.action == "delete":
|
|
try:
|
|
inventory.remove_responseFIR(xresponseFIR.name)
|
|
except KeyError:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
responseFIR = inventory.responseFIR[xresponseFIR.name]
|
|
if responseFIR.publicID != xresponseFIR.publicID:
|
|
inventory.remove_responseFIR(xresponseFIR.name)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
responseFIR = inventory.insert_responseFIR(xresponseFIR.name, publicID=xresponseFIR.publicID)
|
|
xresponseFIR.publicID = responseFIR.publicID
|
|
|
|
xresponseFIR._copy_to(responseFIR)
|
|
|
|
def _responseIIR_in(xresponseIIR, inventory):
|
|
if xresponseIIR.action == "delete":
|
|
try:
|
|
inventory.remove_responseIIR(xresponseIIR.name)
|
|
except KeyError:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
responseIIR = inventory.responseIIR[xresponseIIR.name]
|
|
if responseIIR.publicID != xresponseIIR.publicID:
|
|
inventory.remove_responseIIR(xresponseIIR.name)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
responseIIR = inventory.insert_responseIIR(xresponseIIR.name, publicID=xresponseIIR.publicID)
|
|
xresponseIIR.publicID = responseIIR.publicID
|
|
|
|
xresponseIIR._copy_to(responseIIR)
|
|
|
|
def _responsePAZ_in(xresponsePAZ, inventory):
|
|
if xresponsePAZ.action == "delete":
|
|
try:
|
|
inventory.remove_responsePAZ(xresponsePAZ.name)
|
|
except KeyError:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
responsePAZ = inventory.responsePAZ[xresponsePAZ.name]
|
|
if responsePAZ.publicID != xresponsePAZ.publicID:
|
|
inventory.remove_responsePAZ(xresponsePAZ.name)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
responsePAZ = inventory.insert_responsePAZ(xresponsePAZ.name, publicID=xresponsePAZ.publicID)
|
|
xresponsePAZ.publicID = responsePAZ.publicID
|
|
|
|
xresponsePAZ._copy_to(responsePAZ)
|
|
|
|
def _responsePolynomial_in(xresponsePolynomial, inventory):
|
|
if xresponsePolynomial.action == "delete":
|
|
try:
|
|
inventory.remove_responsePolynomial(xresponsePolynomial.name)
|
|
except KeyError:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
responsePolynomial = inventory.responsePolynomial[xresponsePolynomial.name]
|
|
if responsePolynomial.publicID != xresponsePolynomial.publicID:
|
|
inventory.remove_responsePolynomial(xresponsePolynomial.name)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
responsePolynomial = inventory.insert_responsePolynomial(xresponsePolynomial.name, publicID=xresponsePolynomial.publicID)
|
|
xresponsePolynomial.publicID = responsePolynomial.publicID
|
|
|
|
xresponsePolynomial._copy_to(responsePolynomial)
|
|
|
|
def _responseFAP_in(xresponseFAP, inventory):
|
|
if xresponseFAP.action == "delete":
|
|
try:
|
|
inventory.remove_responseFAP(xresponseFAP.name)
|
|
except KeyError:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
responseFAP = inventory.responseFAP[xresponseFAP.name]
|
|
if responseFAP.publicID != xresponseFAP.publicID:
|
|
inventory.remove_responseFAP(xresponseFAP.name)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
responseFAP = inventory.insert_responseFAP(xresponseFAP.name, publicID=xresponseFAP.publicID)
|
|
xresponseFAP.publicID = responseFAP.publicID
|
|
|
|
xresponseFAP._copy_to(responseFAP)
|
|
|
|
def _decimation_in(xdecim, device):
|
|
if xdecim.action == "delete":
|
|
try:
|
|
device.remove_decimation(xdecim.sampleRateNumerator,
|
|
xdecim.sampleRateDenominator)
|
|
except KeyError:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
decim = device.decimation[xdecim.sampleRateNumerator][xdecim.sampleRateDenominator]
|
|
|
|
except KeyError:
|
|
decim = device.insert_decimation(xdecim.sampleRateNumerator,
|
|
xdecim.sampleRateDenominator)
|
|
|
|
xdecim._copy_to(decim)
|
|
|
|
|
|
|
|
|
|
def _calibration_in(xcalib, device):
|
|
if xcalib.action == "delete":
|
|
try:
|
|
device.remove_calibration(xcalib.serialNumber, xcalib.channel, xcalib.start)
|
|
except KeyError:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
calib = device.calibration[xcalib.serialNumber][xcalib.channel][xcalib.start]
|
|
|
|
except KeyError:
|
|
calib = device.insert_calibration(xcalib.serialNumber, xcalib.channel, xcalib.start)
|
|
|
|
xcalib._copy_to(calib)
|
|
|
|
|
|
def _datalogger_in(xlogger, inventory):
|
|
if xlogger.action == "delete":
|
|
try:
|
|
inventory.remove_datalogger(xlogger.name)
|
|
except KeyError:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
logger = inventory.datalogger[xlogger.name]
|
|
if logger.publicID != xlogger.publicID:
|
|
inventory.remove_datalogger(xlogger.name)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
logger = inventory.insert_datalogger(xlogger.name, publicID=xlogger.publicID)
|
|
xlogger.publicID = logger.publicID
|
|
|
|
xlogger._copy_to(logger)
|
|
|
|
for xdecim in xlogger.decimation:
|
|
_decimation_in(xdecim, logger)
|
|
|
|
for xcalib in xlogger.calibration:
|
|
_calibration_in(xcalib, logger)
|
|
|
|
def _sensor_in(xsensor, inventory):
|
|
if xsensor.action == "delete":
|
|
try:
|
|
inventory.remove_sensor(xsensor.name)
|
|
except KeyError:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
sensor = inventory.sensor[xsensor.name]
|
|
if sensor.publicID != xsensor.publicID:
|
|
inventory.remove_sensor(xsensor.name)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
sensor = inventory.insert_sensor(xsensor.name, publicID=xsensor.publicID)
|
|
xsensor.publicID = sensor.publicID
|
|
|
|
xsensor._copy_to(sensor)
|
|
|
|
for xcalib in xsensor.calibration:
|
|
_calibration_in(xcalib, sensor)
|
|
|
|
def _aux_source_in(xaux_source, auxDevice):
|
|
if xaux_source.action == "delete":
|
|
try:
|
|
auxDevice.remove_auxSource(xaux_source.name)
|
|
except KeyError:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
aux_source = auxDevice.aux_source[xaux_source.name]
|
|
|
|
except KeyError:
|
|
aux_source = auxDevice.insert_auxSource(xaux_source.name)
|
|
|
|
xaux_source._copy_to(aux_source)
|
|
|
|
def _auxDevice_in(xauxDevice, inventory):
|
|
if xauxDevice.action == "delete":
|
|
try:
|
|
inventory.remove_auxDevice(xauxDevice.name)
|
|
except KeyError:
|
|
pass
|
|
|
|
return
|
|
|
|
try:
|
|
auxDevice = inventory.auxDevice[xauxDevice.name]
|
|
if auxDevice.publicID != xauxDevice.publicID:
|
|
inventory.remove_auxDevice(xauxDevice.name)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
auxDevice = inventory.insert_auxDevice(xauxDevice.name, publicID=xauxDevice.publicID)
|
|
xauxDevice.publicID = auxDevice.publicID
|
|
|
|
xauxDevice._copy_to(auxDevice)
|
|
|
|
for xaux_source in xauxDevice.source:
|
|
_aux_source_in(xaux_source, auxDevice)
|
|
|
|
#*****************************************************************************
|
|
# XML IN (stations)
|
|
#*****************************************************************************
|
|
|
|
def _Comment_in(xcom, elem):
|
|
if xcom.action == "delete":
|
|
try:
|
|
elem.remove_comment(xcom.id)
|
|
except KeyError:
|
|
pass
|
|
return
|
|
try:
|
|
com = elem.comment[xcom.id]
|
|
except KeyError:
|
|
com = elem.insert_comment(xcom.id)
|
|
xcom._copy_to(com)
|
|
|
|
|
|
def _AuxStream_in(xaux, sl):
|
|
if xaux.action == "delete":
|
|
try:
|
|
sl.remove_auxStream(xaux.code, xaux.start)
|
|
except KeyError:
|
|
pass
|
|
return
|
|
try:
|
|
aux = sl.auxStream[xaux.code][xaux.start]
|
|
except KeyError:
|
|
aux = sl.insert_auxStream(xaux.code, xaux.start)
|
|
xaux._copy_to(aux)
|
|
|
|
|
|
def _Stream_in(xstrm, sl):
|
|
if xstrm.action == "delete":
|
|
try:
|
|
sl.remove_Stream(xstrm.code, xstrm.start)
|
|
except KeyError:
|
|
pass
|
|
return
|
|
try:
|
|
strm = sl.stream[xstrm.code][xstrm.start]
|
|
if strm.publicID != xstrm.publicID:
|
|
sl.remove_stream(xstrm.code, xstrm.start)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
strm = sl.insert_stream(xstrm.code, xstrm.start, publicID=xstrm.publicID)
|
|
xstrm.publicID = strm.publicID
|
|
|
|
xstrm._copy_to(strm)
|
|
|
|
for xcom in xstrm.comment:
|
|
_Comment_in(xcom, strm)
|
|
|
|
|
|
def _SensorLocation_in(xsl, sta):
|
|
if xsl.action == "delete":
|
|
try:
|
|
sta.remove_sensorLocation(xsl.code, xsl.start)
|
|
except KeyError:
|
|
pass
|
|
return
|
|
try:
|
|
sl = sta.sensorLocation[xsl.code][xsl.start]
|
|
if sl.publicID != xsl.publicID:
|
|
sta.remove_sensorLocation(xsl.code, xsl.start)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
sl = sta.insert_sensorLocation(xsl.code, xsl.start, publicID=xsl.publicID)
|
|
xsl.publicID = sl.publicID
|
|
|
|
xsl._copy_to(sl)
|
|
|
|
for xStream in xsl.stream:
|
|
_Stream_in(xStream, sl)
|
|
|
|
for xAuxStream in xsl.auxStream:
|
|
_AuxStream_in(xAuxStream, sl)
|
|
|
|
for xcom in xsl.comment:
|
|
_Comment_in(xcom, sl)
|
|
|
|
|
|
def _Station_in(xsta, net):
|
|
if xsta.action == "delete":
|
|
try:
|
|
net.remove_station(xsta.code, xsta.start)
|
|
except KeyError:
|
|
pass
|
|
return
|
|
try:
|
|
sta = net.station[xsta.code][xsta.start]
|
|
if sta.publicID != xsta.publicID:
|
|
net.remove_station(xsta.code, xsta.start)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
sta = net.insert_station(xsta.code, xsta.start, publicID=xsta.publicID)
|
|
xsta.publicID = sta.publicID
|
|
|
|
xsta._copy_to(sta)
|
|
|
|
for xsensorLocation in xsta.sensorLocation:
|
|
_SensorLocation_in(xsensorLocation, sta)
|
|
|
|
for xcom in xsta.comment:
|
|
_Comment_in(xcom, sta)
|
|
|
|
|
|
def _Network_in(xnet, inventory):
|
|
if xnet.action == "delete":
|
|
try:
|
|
inventory.remove_network(xnet.code, xnet.start)
|
|
except KeyError:
|
|
pass
|
|
return
|
|
try:
|
|
net = inventory.network[xnet.code][xnet.start]
|
|
if net.publicID != xnet.publicID:
|
|
inventory.remove_network(xnet.code, xnet.start)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
net = inventory.insert_network(xnet.code, xnet.start, publicID=xnet.publicID)
|
|
xnet.publicID = net.publicID
|
|
|
|
xnet._copy_to(net)
|
|
|
|
for xsta in xnet.station:
|
|
_Station_in(xsta, net)
|
|
|
|
for xcom in xnet.comment:
|
|
_Comment_in(xcom, net)
|
|
|
|
|
|
def _StationReference_in(xsref, gr):
|
|
if xsref.action == "delete":
|
|
try:
|
|
inventory.remove_stationReference(xsref.stationID)
|
|
except KeyError:
|
|
pass
|
|
return
|
|
try:
|
|
sref = gr.stationReference[xsref.stationID]
|
|
except KeyError:
|
|
sref = gr.insert_stationReference(xsref.stationID)
|
|
xsref._copy_to(sref)
|
|
|
|
|
|
def _StationGroup_in(xgr, inventory):
|
|
if xgr.action == "delete":
|
|
try:
|
|
inventory.remove_stationGroup(xgr.code)
|
|
except KeyError:
|
|
pass
|
|
return
|
|
try:
|
|
gr = inventory.stationGroup[xgr.code]
|
|
if gr.publicID != xgr.publicID:
|
|
inventory.remove_stationGroup(xgr.code)
|
|
raise KeyError
|
|
|
|
except KeyError:
|
|
gr = inventory.insert_stationGroup(xgr.code, publicID=xgr.publicID)
|
|
xgr.publicID = gr.publicID
|
|
|
|
xgr._copy_to(gr)
|
|
|
|
for xsref in xgr.stationReference:
|
|
_StationReference_in(xsref, gr)
|
|
|
|
|
|
#*****************************************************************************
|
|
# XML IN (doc)
|
|
#*****************************************************************************
|
|
|
|
def _xmldoc_in(xinventory, inventory):
|
|
for xresponseFIR in xinventory.responseFIR:
|
|
_responseFIR_in(xresponseFIR, inventory)
|
|
|
|
for xresponseIIR in xinventory.responseIIR:
|
|
_responseIIR_in(xresponseIIR, inventory)
|
|
|
|
for xresponsePAZ in xinventory.responsePAZ:
|
|
_responsePAZ_in(xresponsePAZ, inventory)
|
|
|
|
for xresponsePolynomial in xinventory.responsePolynomial:
|
|
_responsePolynomial_in(xresponsePolynomial, inventory)
|
|
|
|
for xresponseFAP in xinventory.responseFAP:
|
|
_responseFAP_in(xresponseFAP, inventory)
|
|
|
|
for xsensor in xinventory.sensor:
|
|
_sensor_in(xsensor, inventory)
|
|
|
|
for xlogger in xinventory.datalogger:
|
|
_datalogger_in(xlogger, inventory)
|
|
|
|
for xauxDevice in xinventory.auxDevice:
|
|
_auxDevice_in(xauxDevice, inventory)
|
|
|
|
for xnet in xinventory.network:
|
|
_Network_in(xnet, inventory)
|
|
|
|
for xgr in xinventory.stationGroup:
|
|
_StationGroup_in(xgr, inventory)
|
|
|
|
#*****************************************************************************
|
|
# XML OUT (instruments)
|
|
#*****************************************************************************
|
|
|
|
def _responseFIR_out(xinventory, responseFIR, modified_after):
|
|
if modified_after is None or responseFIR.last_modified >= modified_after:
|
|
xresponseFIR = xinventory._new_responseFIR()
|
|
xresponseFIR._copy_from(responseFIR)
|
|
xinventory._append_child(xresponseFIR)
|
|
return True
|
|
|
|
return False
|
|
|
|
def _responseIIR_out(xinventory, responseIIR, modified_after):
|
|
if modified_after is None or responseIIR.last_modified >= modified_after:
|
|
xresponseIIR = xinventory._new_responseIIR()
|
|
xresponseIIR._copy_from(responseIIR)
|
|
xinventory._append_child(xresponseIIR)
|
|
return True
|
|
|
|
return False
|
|
|
|
def _responsePAZ_out(xinventory, responsePAZ, modified_after):
|
|
if modified_after is None or responsePAZ.last_modified >= modified_after:
|
|
xresponsePAZ = xinventory._new_responsePAZ()
|
|
xresponsePAZ._copy_from(responsePAZ)
|
|
xinventory._append_child(xresponsePAZ)
|
|
return True
|
|
|
|
return False
|
|
|
|
def _responsePolynomial_out(xinventory, responsePolynomial, modified_after):
|
|
if modified_after is None or responsePolynomial.last_modified >= modified_after:
|
|
xresponsePolynomial = xinventory._new_responsePolynomial()
|
|
xresponsePolynomial._copy_from(responsePolynomial)
|
|
xinventory._append_child(xresponsePolynomial)
|
|
return True
|
|
|
|
return False
|
|
|
|
def _responseFAP_out(xinventory, responseFAP, modified_after):
|
|
if modified_after is None or responseFAP.last_modified >= modified_after:
|
|
xresponseFAP = xinventory._new_responseFAP()
|
|
xresponseFAP._copy_from(responseFAP)
|
|
xinventory._append_child(xresponseFAP)
|
|
return True
|
|
|
|
return False
|
|
|
|
def _decimation_out(xdevice, decim, modified_after, filters):
|
|
if filters is not None:
|
|
for f in str(decim.digitalFilterChain).split():
|
|
filters.reg_filter(f)
|
|
for f in str(decim.analogueFilterChain).split():
|
|
filters.reg_filter(f)
|
|
|
|
if modified_after is None or decim.last_modified >= modified_after:
|
|
xdecim = xdevice._new_decimation()
|
|
xdecim._copy_from(decim)
|
|
xdevice._append_child(xdecim)
|
|
return True
|
|
|
|
return False
|
|
|
|
def _gain_out(xcalib, gain, modified_after):
|
|
if modified_after is None or gain.last_modified >= modified_after:
|
|
xgain = xcalib._new_gain()
|
|
xgain._copy_from(gain)
|
|
xcalib._append_child(xgain)
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
def _dataloggerCalibration_out(xdevice, calib, modified_after):
|
|
xcalib = xdevice._new_calibration()
|
|
|
|
if modified_after is None or calib.last_modified >= modified_after:
|
|
xcalib._copy_from(calib)
|
|
retval = True
|
|
else:
|
|
xcalib.serialNumber = calib.serialNumber
|
|
retval = False
|
|
|
|
if retval:
|
|
xdevice._append_child(xcalib)
|
|
|
|
return retval
|
|
|
|
def _sensorCalibration_out(xdevice, calib, modified_after):
|
|
xcalib = xdevice._new_calibration()
|
|
|
|
if modified_after is None or calib.last_modified >= modified_after:
|
|
xcalib._copy_from(calib)
|
|
retval = True
|
|
else:
|
|
xcalib.serialNumber = calib.serialNumber
|
|
retval = False
|
|
|
|
if retval:
|
|
xdevice._append_child(xcalib)
|
|
|
|
return retval
|
|
|
|
|
|
def _datalogger_out(xinventory, logger, modified_after, used, filters):
|
|
xlogger = xinventory._new_datalogger()
|
|
|
|
if modified_after is None or logger.last_modified >= modified_after:
|
|
xlogger._copy_from(logger)
|
|
retval = True
|
|
else:
|
|
xlogger.publicID = logger.publicID
|
|
retval = False
|
|
|
|
for i in logger.decimation.values():
|
|
for j in i.values():
|
|
if used is None or \
|
|
(j.sampleRateNumerator, j.sampleRateDenominator) in used.decimation:
|
|
retval |= _decimation_out(xlogger, j, modified_after, filters)
|
|
|
|
for c in [t for sn in logger.calibration.values()\
|
|
for ch in sn.values()\
|
|
for t in ch.values()]:
|
|
if used is None or c.serialNumber in used.calibration:
|
|
retval |= _dataloggerCalibration_out(xlogger, c, modified_after)
|
|
|
|
if retval:
|
|
xinventory._append_child(xlogger)
|
|
|
|
return retval
|
|
|
|
def _sensor_out(xinventory, sensor, modified_after, used, filters):
|
|
xsensor = xinventory._new_sensor()
|
|
if filters is not None and sensor.response != "":
|
|
filters.reg_filter(sensor.response)
|
|
|
|
if modified_after is None or sensor.last_modified >= modified_after:
|
|
xsensor._copy_from(sensor)
|
|
retval = True
|
|
else:
|
|
xsensor.publicID = sensor.publicID
|
|
retval = False
|
|
|
|
for c in [t for sn in sensor.calibration.values()\
|
|
for ch in sn.values()\
|
|
for t in ch.values()]:
|
|
if used is None or c.serialNumber in used.calibration:
|
|
retval |= _sensorCalibration_out(xsensor, c, modified_after)
|
|
|
|
if retval:
|
|
xinventory._append_child(xsensor)
|
|
|
|
return retval
|
|
|
|
def _aux_source_out(xauxDevice, aux_source, modified_after):
|
|
if modified_after is None or aux_source.last_modified >= modified_after:
|
|
xaux_source = xauxDevice._new_source()
|
|
xaux_source._copy_from(aux_source)
|
|
xauxDevice._append_child(xaux_source)
|
|
return True
|
|
|
|
return False
|
|
|
|
def _auxDevice_out(xinventory, auxDevice, modified_after, used):
|
|
xauxDevice = xinventory._new_auxDevice()
|
|
|
|
if modified_after is None or auxDevice.last_modified >= modified_after:
|
|
xauxDevice._copy_from(auxDevice)
|
|
retval = True
|
|
else:
|
|
xauxDevice.publicID = auxDevice.publicID
|
|
retval = False
|
|
|
|
for i in auxDevice.source.values():
|
|
if used is None or i.name in used.source:
|
|
retval |= _aux_source_out(xauxDevice, i, modified_after)
|
|
|
|
if retval:
|
|
xinventory._append_child(xauxDevice)
|
|
|
|
return retval
|
|
|
|
#*****************************************************************************
|
|
# XML OUT (stations)
|
|
#*****************************************************************************
|
|
|
|
|
|
def _Comment_out(xelem, com, modified_after, used_instr):
|
|
if modified_after is None or com.last_modified >= modified_after:
|
|
xcom = xelem._new_comment()
|
|
xcom._copy_from(com)
|
|
xelem._append_child(xcom)
|
|
return True
|
|
return False
|
|
|
|
|
|
|
|
def _Stream_out(xsl, strm, modified_after, used_instr):
|
|
if used_instr is not None:
|
|
used_sensor = used_instr.reg_sensor(strm.sensor)
|
|
if strm.sensorSerialNumber != "":
|
|
used_sensor.reg_calibration(strm.sensorSerialNumber)
|
|
used_logger = used_instr.reg_datalogger(strm.datalogger)
|
|
used_logger.reg_decimation(strm.sampleRateNumerator, strm.sampleRateDenominator)
|
|
if strm.dataloggerSerialNumber != "":
|
|
used_logger.reg_calibration(strm.dataloggerSerialNumber)
|
|
if modified_after is None or strm.last_modified >= modified_after:
|
|
xstrm = xsl._new_stream()
|
|
xstrm._copy_from(strm)
|
|
retval = True
|
|
else:
|
|
xstrm.code = strm.code
|
|
xstrm.start = strm.start
|
|
retval = False
|
|
for i in strm.comment.values():
|
|
retval |= _Comment_out(xstrm, i, modified_after, used_instr)
|
|
if retval:
|
|
xsl._append_child(xstrm)
|
|
return retval
|
|
|
|
|
|
|
|
def _AuxStream_out(xsl, aux, modified_after, used_instr):
|
|
if used_instr is not None:
|
|
used_auxDevice = used_instr.reg_auxDevice(aux.device)
|
|
used_auxDevice.reg_source(aux.source)
|
|
if modified_after is None or aux.last_modified >= modified_after:
|
|
xaux = xsl._new_auxStream()
|
|
xaux._copy_from(aux)
|
|
xsl._append_child(xaux)
|
|
return True
|
|
return False
|
|
|
|
|
|
|
|
|
|
def _SensorLocation_out(xsta, sl, modified_after, used_instr):
|
|
xsl = xsta._new_sensorLocation()
|
|
if modified_after is None or sl.last_modified >= modified_after:
|
|
xsl._copy_from(sl)
|
|
retval = True
|
|
else:
|
|
xsl.code = sl.code
|
|
xsl.start = sl.start
|
|
retval = False
|
|
for i in sl.stream.values():
|
|
for j in i.values():
|
|
retval |= _Stream_out(xsl, j, modified_after, used_instr)
|
|
for i in sl.auxStream.values():
|
|
for j in i.values():
|
|
retval |= _AuxStream_out(xsl, j, modified_after, used_instr)
|
|
for i in sl.comment.values():
|
|
retval |= _Comment_out(xsl, i, modified_after, used_instr)
|
|
if retval:
|
|
xsta._append_child(xsl)
|
|
return retval
|
|
|
|
|
|
|
|
|
|
def _Station_out(xnet, sta, modified_after, used_instr):
|
|
xsta = xnet._new_station()
|
|
if modified_after is None or sta.last_modified >= modified_after:
|
|
xsta._copy_from(sta)
|
|
retval = True
|
|
else:
|
|
xsta.code = sta.code
|
|
xsta.start = sta.start
|
|
retval = False
|
|
for i in sta.sensorLocation.values():
|
|
for j in i.values():
|
|
retval |= _SensorLocation_out(xsta, j, modified_after, used_instr)
|
|
for i in sta.comment.values():
|
|
retval |= _Comment_out(xsta, i, modified_after, used_instr)
|
|
if retval:
|
|
xnet._append_child(xsta)
|
|
return retval
|
|
|
|
|
|
|
|
|
|
def _Network_out(xinventory, net, modified_after, used_instr):
|
|
xnet = xinventory._new_network()
|
|
if modified_after is None or net.last_modified >= modified_after:
|
|
xnet._copy_from(net)
|
|
retval = True
|
|
else:
|
|
xnet.code = net.code
|
|
xnet.start = net.start
|
|
retval = False
|
|
for i in net.station.values():
|
|
for j in i.values():
|
|
retval |= _Station_out(xnet, j, modified_after, used_instr)
|
|
for i in net.comment.values():
|
|
retval |= _Comment_out(xnet, i, modified_after, used_instr)
|
|
if retval:
|
|
xinventory._append_child(xnet)
|
|
return retval
|
|
|
|
|
|
|
|
|
|
def _StationReference_out(xgr, sref, modified_after, used_instr):
|
|
xsref = xgr._new_stationReference()
|
|
xsref._copy_from(sref)
|
|
xgr._append_child(xsref)
|
|
return True
|
|
|
|
|
|
|
|
def _StationGroup_out(xinventory, gr, modified_after, used_instr):
|
|
if modified_after is None or gr.last_modified >= modified_after:
|
|
xgr = xinventory._new_stationGroup()
|
|
xgr._copy_from(gr)
|
|
xinventory._append_child(xgr)
|
|
for i in gr.stationReference.values():
|
|
_StationReference_out(xgr, i, modified_after, used_instr)
|
|
return True
|
|
|
|
return False
|
|
|
|
#*****************************************************************************
|
|
# XML OUT (doc)
|
|
#*****************************************************************************
|
|
|
|
def _xmldoc_out(xinventory, inventory, instr, modified_after):
|
|
if instr == 0:
|
|
for i in inventory.network.values():
|
|
for j in i.values():
|
|
_Network_out(xinventory, j, modified_after, None)
|
|
|
|
for i in inventory.stationGroup.values():
|
|
_StationGroup_out(xinventory, i, modified_after, None)
|
|
|
|
elif instr == 1:
|
|
used_instr = _UsedInstruments()
|
|
used_filters = _UsedFilters()
|
|
|
|
for i in inventory.network.values():
|
|
for j in i.values():
|
|
_Network_out(xinventory, j, modified_after, used_instr)
|
|
|
|
for i in inventory.stationGroup.values():
|
|
_StationGroup_out(xinventory, i, modified_after, None)
|
|
|
|
for i in inventory.datalogger.values():
|
|
used_logger = used_instr.datalogger.get(i.publicID)
|
|
if used_logger is not None:
|
|
_datalogger_out(xinventory, i, modified_after, used_logger, used_filters)
|
|
|
|
for i in inventory.sensor.values():
|
|
used_sensor = used_instr.sensor.get(i.publicID)
|
|
if used_sensor is not None:
|
|
_sensor_out(xinventory, i, modified_after, used_sensor, used_filters)
|
|
|
|
for i in inventory.auxDevice.values():
|
|
used_auxDevice = used_instr.auxDevice.get(i.publicID)
|
|
if used_auxDevice is not None:
|
|
_auxDevice_out(xinventory, i, modified_after, used_auxDevice)
|
|
|
|
for i in inventory.responseFIR.values():
|
|
if i.publicID in used_filters.filters:
|
|
_responseFIR_out(xinventory, i, modified_after)
|
|
|
|
for i in inventory.responseIIR.values():
|
|
if i.publicID in used_filters.filters:
|
|
_responseIIR_out(xinventory, i, modified_after)
|
|
|
|
for i in inventory.responsePAZ.values():
|
|
if i.publicID in used_filters.filters:
|
|
_responsePAZ_out(xinventory, i, modified_after)
|
|
|
|
for i in inventory.responsePolynomial.values():
|
|
if i.publicID in used_filters.filters:
|
|
_responsePolynomial_out(xinventory, i, modified_after)
|
|
|
|
for i in inventory.responseFAP.values():
|
|
if i.publicID in used_filters.filters:
|
|
_responseFAP_out(xinventory, i, modified_after)
|
|
elif instr == 2:
|
|
for i in inventory.network.values():
|
|
for j in i.values():
|
|
_Network_out(xinventory, j, modified_after, None)
|
|
|
|
for i in inventory.stationGroup.values():
|
|
_StationGroup_out(xinventory, i, modified_after, None)
|
|
|
|
for i in inventory.datalogger.values():
|
|
_datalogger_out(xinventory, i, modified_after, None, None)
|
|
|
|
for i in inventory.sensor.values():
|
|
_sensor_out(xinventory, i, modified_after, None, None)
|
|
|
|
for i in inventory.auxDevice.values():
|
|
_auxDevice_out(xinventory, i, modified_after, used_auxDevice)
|
|
|
|
for i in inventory.responseFIR.values():
|
|
_responseFIR_out(xinventory, i, modified_after)
|
|
|
|
for i in inventory.responseIIR.values():
|
|
_responseIIR_out(xinventory, i, modified_after)
|
|
|
|
for i in inventory.responsePAZ.values():
|
|
_responsePAZ_out(xinventory, i, modified_after)
|
|
|
|
for i in inventory.responsePolynomial.values():
|
|
_responsePolynomial_out(xinventory, i, modified_after)
|
|
|
|
for i in inventory.responseFAP.values():
|
|
_responseFAP_out(xinventory, i, modified_after)
|
|
|
|
#*****************************************************************************
|
|
# Incremental Parser
|
|
#*****************************************************************************
|
|
|
|
class _IncrementalParser(object):
|
|
def __init__(self, inventory):
|
|
self.__inventory = inventory
|
|
self.__p = ET.XMLTreeBuilder()
|
|
|
|
def feed(self, s):
|
|
self.__p.feed(s)
|
|
|
|
def close(self):
|
|
root = self.__p.close()
|
|
if root.tag != _root_tag:
|
|
raise DBError("unrecognized root element: " + root.tag)
|
|
|
|
xinventory = _xmlwrap.xml_Inventory(root)
|
|
_xmldoc_in(xinventory, self.__inventory)
|
|
|
|
#*****************************************************************************
|
|
# Public functions
|
|
#*****************************************************************************
|
|
|
|
def make_parser(inventory):
|
|
return _IncrementalParser(inventory)
|
|
|
|
def xml_in(inventory, src):
|
|
doc = ET.parse(src)
|
|
root = doc.getroot()
|
|
if root.tag != _root_tag:
|
|
raise DBError("unrecognized root element: " + root.tag)
|
|
|
|
xinventory = _xmlwrap.xml_Inventory(root)
|
|
_xmldoc_in(xinventory, inventory)
|
|
|
|
def _indent(elem, level=0):
|
|
s = 1*"\t" # indent char
|
|
i = "\n" + level*s
|
|
if len(elem):
|
|
if not elem.text or not elem.text.strip():
|
|
elem.text = i + s
|
|
for e in elem:
|
|
_indent(e, level+1)
|
|
if not e.tail or not e.tail.strip():
|
|
e.tail = i + s
|
|
if not e.tail or not e.tail.strip():
|
|
e.tail = i
|
|
else:
|
|
if level and (not elem.tail or not elem.tail.strip()):
|
|
elem.tail = i
|
|
|
|
def xml_out(inventory, dest, instr=0, modified_after=None, stylesheet=None, indent=True):
|
|
xinventory = _xmlwrap.xml_Inventory()
|
|
|
|
_xmldoc_out(xinventory, inventory, instr, modified_after)
|
|
|
|
if isinstance(dest, str):
|
|
fd = open(dest, "wb")
|
|
elif hasattr(dest, "write"):
|
|
fd = dest
|
|
else:
|
|
raise TypeError("invalid file object")
|
|
|
|
try:
|
|
filename = fd.name
|
|
except AttributeError:
|
|
filename = '<???>'
|
|
|
|
fd.write(b'<?xml version="1.0" encoding="utf-8"?>\n')
|
|
|
|
if stylesheet is not None:
|
|
fd.write(b'<?xml-stylesheet type="application/xml" href="%s"?>\n' % \
|
|
(stylesheet,))
|
|
|
|
if indent is True:
|
|
_indent(xinventory._element)
|
|
|
|
ET.ElementTree(xinventory._element).write(fd, encoding="utf-8")
|
|
|
|
if isinstance(dest, str):
|
|
fd.close()
|
|
|