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.
367 lines
16 KiB
Python
367 lines
16 KiB
Python
from __future__ import print_function
|
|
import seiscomp.datamodel, seiscomp.core, seiscomp.config
|
|
from .helpers import parsers
|
|
import datetime
|
|
import sys
|
|
|
|
|
|
class sc3(object):
|
|
def _fillSc3(self, obj, att):
|
|
commentNum = 0
|
|
for (k, p) in att.items():
|
|
try:
|
|
if k == 'Comment':
|
|
# print('DEBUG: Adding comment', p)
|
|
if p.startswith('Grant'):
|
|
# 2020: These belong in DOI metadata, not here.
|
|
continue
|
|
|
|
c = seiscomp.datamodel.Comment()
|
|
c.setText(p)
|
|
c.setId(str(commentNum))
|
|
commentNum += 1
|
|
obj.add(c)
|
|
continue
|
|
|
|
if k == 'Pid':
|
|
# print('DEBUG: Adding Pid as comment', p)
|
|
c = seiscomp.datamodel.Comment()
|
|
(typ, val) = p.split(':', 1)
|
|
s = '{"type":"%s", "value":"%s"}' % (typ.upper(), val)
|
|
c.setText(s)
|
|
c.setId('FDSNXML:Identifier/' + str(commentNum))
|
|
commentNum += 1
|
|
obj.add(c)
|
|
continue
|
|
|
|
w = 'set' + k
|
|
p = self.sc3Valid['attributes'][k]['validator'](p)
|
|
getattr(obj, w)(p)
|
|
except Exception as e:
|
|
print("[Error] %s = %s (%s)" % (k, p, e),
|
|
file=sys.stderr)
|
|
|
|
@staticmethod
|
|
def getBool(val):
|
|
if val == "True" or val == 1:
|
|
return True
|
|
elif val == "False" or val == 0:
|
|
return False
|
|
else:
|
|
raise Exception("Invalid Boolean Value")
|
|
|
|
@staticmethod
|
|
def getString(data):
|
|
return data.strip()
|
|
|
|
@staticmethod
|
|
def getRealArray(data):
|
|
RA = seiscomp.datamodel.RealArray()
|
|
for r in map(float, data):
|
|
RA.content().push_back(r)
|
|
return RA
|
|
|
|
@staticmethod
|
|
def getComplexArray(data):
|
|
CA = seiscomp.datamodel.ComplexArray()
|
|
for (r,i) in data:
|
|
CA.content().push_back(complex(float(r),float(i)))
|
|
return CA
|
|
|
|
@staticmethod
|
|
def getDate(value):
|
|
if isinstance(value, datetime.datetime):
|
|
return seiscomp.core.Time(*(value.timetuple()[:6]))
|
|
elif isinstance(value, str):
|
|
value = parsers.parseDate(value)
|
|
return seiscomp.core.Time(*(value.timetuple()[:6]))
|
|
return value
|
|
|
|
@staticmethod
|
|
def getBlob(value):
|
|
b = seiscomp.datamodel.Blob()
|
|
b.setContent(value)
|
|
return b
|
|
|
|
@staticmethod
|
|
def getStationGroupType(val):
|
|
if val == "ARRAY":
|
|
return seiscomp.datamodel.ARRAY
|
|
elif val == "DEPLOYMENT":
|
|
return seiscomp.datamodel.DEPLOYMENT
|
|
else:
|
|
raise Exception("Invalid station group type")
|
|
|
|
@staticmethod
|
|
def _findValidOnes(mode):
|
|
valid = {
|
|
'dataloggerCalibration': {
|
|
'creator': seiscomp.datamodel.DataloggerCalibration,
|
|
'attributes': {
|
|
'SerialNumber': { 'validator': sc3.getString },
|
|
'Channel': { 'validator': int },
|
|
'Start': { 'validator': sc3.getDate },
|
|
'End': { 'validator': sc3.getDate },
|
|
'Gain': { 'validator': float },
|
|
'GainFrequency': { 'validator': float },
|
|
'Remark': { 'validator': sc3.getBlob }
|
|
}
|
|
},
|
|
'sensorCalibration': {
|
|
'creator': seiscomp.datamodel.SensorCalibration,
|
|
'attributes': {
|
|
'SerialNumber': { 'validator': sc3.getString },
|
|
'Channel': { 'validator': int },
|
|
'Start': { 'validator': sc3.getDate },
|
|
'End': { 'validator': sc3.getDate },
|
|
'Gain': { 'validator': float },
|
|
'GainFrequency': { 'validator': float },
|
|
'Remark': { 'validator': sc3.getBlob }
|
|
}
|
|
},
|
|
'channel': {
|
|
'creator': seiscomp.datamodel.Stream_Create,
|
|
'attributes': {
|
|
'Code': { 'validator': sc3.getString },
|
|
'Start': { 'validator': sc3.getDate },
|
|
'End': { 'validator': sc3.getDate },
|
|
'Datalogger': { 'validator': sc3.getString },
|
|
'DataloggerSerialNumber': { 'validator': sc3.getString },
|
|
'DataloggerChannel': { 'validator': int },
|
|
'Sensor': { 'validator': sc3.getString },
|
|
'SensorSerialNumber': { 'validator': sc3.getString },
|
|
'SensorChannel': { 'validator': int },
|
|
'ClockSerialNumber': { 'validator': sc3.getString },
|
|
'SampleRateNumerator': { 'validator': int },
|
|
'SampleRateDenominator': { 'validator': int },
|
|
'Depth': { 'validator': float },
|
|
'Azimuth': { 'validator': float },
|
|
'Dip': { 'validator': float },
|
|
'Gain': { 'validator': float },
|
|
'GainFrequency': { 'validator': float },
|
|
'GainUnit': { 'validator': sc3.getString },
|
|
'Format': { 'validator': sc3.getString },
|
|
'Flags': { 'validator': sc3.getString },
|
|
'Restricted': { 'validator': sc3.getBool },
|
|
'Shared': { 'validator': sc3.getBool }
|
|
}
|
|
},
|
|
'location': {
|
|
'creator': seiscomp.datamodel.SensorLocation_Create,
|
|
'attributes': {
|
|
'Code': { 'validator': sc3.getString },
|
|
'Start': { 'validator': sc3.getDate },
|
|
'End': { 'validator': sc3.getDate },
|
|
"Latitude": { 'validator': float },
|
|
"Longitude": { 'validator': float },
|
|
"Elevation": { 'validator': float }
|
|
}
|
|
},
|
|
'station': {
|
|
'creator': seiscomp.datamodel.Station_Create,
|
|
'attributes': {
|
|
'Code': { 'validator': sc3.getString },
|
|
'Start': { 'validator': sc3.getDate },
|
|
'End': { 'validator': sc3.getDate },
|
|
'Description': { 'validator': sc3.getString },
|
|
'Latitude': { 'validator': float },
|
|
'Longitude': { 'validator': float },
|
|
'Elevation': { 'validator': float },
|
|
'Place': { 'validator': sc3.getString },
|
|
'Country': { 'validator': sc3.getString },
|
|
'Affiliation': { 'validator': sc3.getString },
|
|
'Type': { 'validator': sc3.getString },
|
|
'ArchiveNetworkCode': { 'validator': sc3.getString },
|
|
'Archive': { 'validator': sc3.getString },
|
|
'Restricted': { 'validator': sc3.getBool },
|
|
'Shared': { 'validator': sc3.getBool },
|
|
'Remark': { 'validator': sc3.getBlob }
|
|
}
|
|
},
|
|
'network': {
|
|
'creator': seiscomp.datamodel.Network_Create,
|
|
'attributes': {
|
|
'Code': { 'validator': sc3.getString },
|
|
'Start': { 'validator': sc3.getDate },
|
|
'End': { 'validator': sc3.getDate },
|
|
'Description': { 'validator': sc3.getString },
|
|
'Institutions': { 'validator': sc3.getString },
|
|
'Region': { 'validator': sc3.getString },
|
|
'Type': { 'validator': sc3.getString },
|
|
'NetClass': { 'validator': sc3.getString },
|
|
'Archive': { 'validator': sc3.getString },
|
|
'Comment': { 'validator': sc3.getString },
|
|
'Pid': { 'validator': sc3.getBlob },
|
|
'Restricted': { 'validator': sc3.getBool },
|
|
'Shared': { 'validator': sc3.getBool },
|
|
'Remark': { 'validator': sc3.getBlob }
|
|
}
|
|
},
|
|
'stationGroup': {
|
|
'creator': seiscomp.datamodel.StationGroup_Create,
|
|
'attributes': {
|
|
'Code': { 'validator': sc3.getString },
|
|
'Start': { 'validator': sc3.getDate },
|
|
'End': { 'validator': sc3.getDate },
|
|
'Description': { 'validator': sc3.getString },
|
|
'Type': { 'validator': sc3.getStationGroupType },
|
|
'Latitude': { 'validator': float },
|
|
'Longitude': { 'validator': float },
|
|
'Elevation': { 'validator': float },
|
|
}
|
|
},
|
|
'stationReference': {
|
|
'creator': seiscomp.datamodel.StationReference,
|
|
'attributes': {
|
|
'StationID': { 'validator': sc3.getString },
|
|
}
|
|
},
|
|
'datalogger': {
|
|
'creator': seiscomp.datamodel.Datalogger_Create,
|
|
'attributes': {
|
|
'Name': { 'validator': sc3.getString },
|
|
'Description': { 'validator': sc3.getString },
|
|
'DigitizerModel': { 'validator': sc3.getString },
|
|
'DigitizerManufacturer': { 'validator': sc3.getString },
|
|
'RecorderModel': { 'validator': sc3.getString },
|
|
'RecorderManufacturer': { 'validator': sc3.getString },
|
|
'ClockModel': { 'validator': sc3.getString },
|
|
'ClockManufacturer': { 'validator': sc3.getString },
|
|
'ClockType': { 'validator': sc3.getString },
|
|
'Gain': { 'validator': float },
|
|
'MaxClockDrift': { 'validator': float },
|
|
'Remark': { 'validator': sc3.getBlob }
|
|
}
|
|
},
|
|
'decimation': {
|
|
'creator': seiscomp.datamodel.Decimation,
|
|
'attributes': {
|
|
'SampleRateNumerator': { 'validator': int },
|
|
'SampleRateDenominator': { 'validator': int },
|
|
'AnalogueFilterChain': { 'validator': sc3.getBlob },
|
|
'DigitalFilterChain': { 'validator': sc3.getBlob }
|
|
}
|
|
},
|
|
'fir': {
|
|
'creator': seiscomp.datamodel.ResponseFIR_Create,
|
|
'attributes': {
|
|
"Name": { 'validator': sc3.getString },
|
|
"Gain": { 'validator': float },
|
|
"DecimationFactor": { 'validator': int },
|
|
"Delay": { 'validator': float },
|
|
"Correction": { 'validator': float },
|
|
"NumberOfCoefficients": { 'validator': int },
|
|
"Symmetry": { 'validator': sc3.getString },
|
|
"Coefficients": { 'validator': sc3.getRealArray },
|
|
"Remarks": { 'validator': sc3.getBlob }
|
|
}
|
|
},
|
|
'paz': {
|
|
'creator': seiscomp.datamodel.ResponsePAZ_Create,
|
|
'attributes': {
|
|
'Name': { 'validator': sc3.getString },
|
|
'Description': { 'validator': sc3.getString },
|
|
'Type': { 'validator': sc3.getString },
|
|
'Gain': { 'validator': float },
|
|
'GainFrequency': { 'validator': float },
|
|
'NormalizationFactor': { 'validator': float },
|
|
'NormalizationFrequency': { 'validator': float },
|
|
'NumberOfZeros': { 'validator': int },
|
|
'NumberOfPoles': { 'validator': int },
|
|
'Zeros': { 'validator': sc3.getComplexArray },
|
|
'Poles': { 'validator': sc3.getComplexArray },
|
|
'Remark': { 'validator': sc3.getBlob }
|
|
}
|
|
},
|
|
'sensor': {
|
|
'creator': seiscomp.datamodel.Sensor_Create,
|
|
'attributes': {
|
|
'Name': { 'validator': sc3.getString },
|
|
'Description': { 'validator': sc3.getString },
|
|
'Model': { 'validator': sc3.getString },
|
|
'Manufacturer': { 'validator': sc3.getString },
|
|
'Type': { 'validator': sc3.getString },
|
|
'Unit': { 'validator': sc3.getString },
|
|
'LowFrequency': { 'validator': float },
|
|
'HighFrequency': { 'validator': float },
|
|
'Response': { 'validator': sc3.getString },
|
|
'Remark': { 'validator': sc3.getBlob }
|
|
}
|
|
}
|
|
}
|
|
|
|
return(valid.get(mode))
|
|
|
|
def __init__(self, mode, child=[]):
|
|
self.sc3Mode = mode
|
|
self.sc3obj = None
|
|
self.sc3Valid = sc3._findValidOnes(mode)
|
|
self._sc3Childs = child
|
|
|
|
def _create(self):
|
|
if not self.sc3Valid:
|
|
raise Exception("Class without a type defined.")
|
|
return self.sc3Valid['creator']()
|
|
|
|
def sc3Att(self):
|
|
"""
|
|
This is the heart. You should return an dictionary of attributes to be
|
|
setted on the sc3 object. This dictionary will be used by the _fillSc3
|
|
method.
|
|
"""
|
|
raise Exception("Not Implemented !")
|
|
|
|
def sc3ValidKey(self, key):
|
|
if not self.sc3Valid:
|
|
raise Exception("Class without a type defined.")
|
|
return (key in self.sc3Valid['attributes'])
|
|
|
|
def sc3Resolv(self, inventory):
|
|
"""
|
|
In this method you should be able to resolv all the references in your
|
|
self object.
|
|
"""
|
|
pass
|
|
|
|
def sc3Derived(self, inventory):
|
|
"""
|
|
This method should generate and collect all the derived objects
|
|
(child on the inventory sense) that should be attributed to the self
|
|
object. By default on this virtual method is returns an empty array.
|
|
"""
|
|
objs = []
|
|
for obj in self._sc3Childs:
|
|
objs.append(obj.sc3Obj(inventory))
|
|
return objs
|
|
|
|
def sc3ID(self, inventory):
|
|
obj = self.sc3Obj(inventory)
|
|
return obj.publicID()
|
|
|
|
def sc3Obj(self, inventory):
|
|
if not self.sc3obj:
|
|
# Get a new object
|
|
obj = self._create()
|
|
|
|
# try to resolve REFERENCES to PUBLIC ID
|
|
self.sc3Resolv(inventory)
|
|
|
|
# Add the derived objects in
|
|
for dobj in self.sc3Derived(inventory):
|
|
obj.add(dobj)
|
|
|
|
# Fill the Attributes in
|
|
self._fillSc3(obj, self.sc3Att())
|
|
# # Only want to see Networks:
|
|
# if (('Code' in self.sc3Att().keys())
|
|
# and ('ArchiveNetworkCode' not in self.sc3Att().keys())
|
|
# and ('Azimuth' not in self.sc3Att().keys())
|
|
# ):
|
|
# print('DEBUG basesc3.py: sc3Obj:', self, self.sc3Att())
|
|
|
|
# Set as created
|
|
self.sc3obj = obj
|
|
|
|
# return the obj
|
|
return self.sc3obj
|