Exemple #1
0
    def init(self):
        if not Client.Application.init(self): return False

        try:
            cstr = self.commandline().optionString("coord")
            tstr = self.commandline().optionString("time")
        except:
            sys.stderr.write(
                "must specify origin using '--coord lat,lon,dep --time time'\n"
            )
            return False

        self.origin = DataModel.Origin.Create()

        ci = DataModel.CreationInfo()
        ci.setAgencyID(self.agencyID())
        ci.setCreationTime(Core.Time.GMT())
        self.origin.setCreationInfo(ci)

        lat, lon, dep = map(float, cstr.split(","))
        self.origin.setLongitude(DataModel.RealQuantity(lon))
        self.origin.setLatitude(DataModel.RealQuantity(lat))
        self.origin.setDepth(DataModel.RealQuantity(dep))

        time = Core.Time()
        time.fromString(tstr.replace("/", "-") + ":0:0", "%F %T")
        self.origin.setTime(DataModel.TimeQuantity(time))

        return True
Exemple #2
0
 def updateOrigin(self,
                  origin,
                  PID=None,
                  ot=None,
                  lat=None,
                  lon=None,
                  depth=None,
                  mag=None,
                  otu=None,
                  latu=None,
                  magu=None,
                  lonu=None,
                  depthu=None,
                  creationTime=None,
                  modificationTime=None):
     if PID:
         origin.setPublicID(PID)
     if ot:
         origin.setTime(scdatamodel.TimeQuantity(ot))
     if lat:
         origin.setLatitude(scdatamodel.RealQuantity(float(lat)))
     if lon:
         origin.setLongitude(scdatamodel.RealQuantity(float(lon)))
     if depth:
         origin.setDepth(scdatamodel.RealQuantity(float(depth)))
     if latu:
         origin.latitude().setUncertainty(float(latu))
     if lonu:
         origin.longitude().setUncertainty(float(lonu))
     if depthu:
         origin.depth().setUncertainty(float(depthu))
     if otu:
         origin.time().setUncertainty(float(otu))
     if creationTime:
         ci = origin.creationInfo()
         ci.setCreationTime(creationTime)
     if modificationTime:
         ci = origin.creationInfo()
         ci.setModificationTime(creationTime)
     if mag or magu:
         m = origin.magnitude(0)
         if mag: m.setMagnitude(scdatamodel.RealQuantity(mag))
         if magu: m.magnitude().setUncertainty(magu)
         if modificationTime:
             ci = m.creationInfo()
             ci.setModificationTime(creationTime)
Exemple #3
0
 def createOrigin(self,
                  ot,
                  lat,
                  lon,
                  depth=8,
                  otu=0,
                  latu=0,
                  lonu=0,
                  depthu=0,
                  mag=-99,
                  magu=0,
                  reported=0,
                  creationTime=None,
                  agencyID=AGENCYID,
                  author=AUTHOR):
     if not creationTime: creationTime = sccore.Time.GMT()
     lat, lon, depth, otu, latu, lonu, depthu = [
         float(i) for i in lat, lon, depth, otu, latu, lonu, depthu
     ]  # convert values to floats
     origin = scdatamodel.Origin('')
     self.eparams.GenerateId(origin)
     origin.setLongitude(scdatamodel.RealQuantity(lon))
     origin.longitude().setUncertainty(lonu)
     origin.setLatitude(scdatamodel.RealQuantity(lat))
     origin.latitude().setUncertainty(latu)
     origin.setDepth(scdatamodel.RealQuantity(depth))
     origin.depth().setUncertainty(depthu)
     origin.setTime(scdatamodel.TimeQuantity(ot))
     origin.time().setUncertainty(otu)
     origin.setEvaluationMode(1)
     if int(reported):
         origin.setEvaluationStatus(scdatamodel.REPORTED)
     else:
         origin.setEvaluationStatus(scdatamodel.PRELIMINARY)
     self.addCreationInfo(origin,
                          creationTime=creationTime,
                          agencyID=AGENCYID,
                          author=AUTHOR)
     self.addMagnitude(origin,
                       magval=mag,
                       magu=magu,
                       creationTime=creationTime)
     return origin
Exemple #4
0
 def addMagnitude(self,
                  parent,
                  magval,
                  magu=0,
                  creationTime=None,
                  agencyID=AGENCYID,
                  author=AUTHOR):
     magval = float(magval)
     magu = float(magu)
     if not creationTime: creationTime = sccore.Time.GMT()
     mag = scdatamodel.Magnitude('')
     self.eparams.GenerateId(mag, parent.publicID() + '#netMag.M')
     mag.setMagnitude(scdatamodel.RealQuantity(magval))
     mag.magnitude().setUncertainty(magu)
     self.addCreationInfo(mag, creationTime, agencyID, author)
     mag.setType('M')
     parent.add(mag)
Exemple #5
0
 def addStationMagnitude(self,
                         parent,
                         magval,
                         amp,
                         weight=1,
                         creationTime=None,
                         agencyID=AGENCYID,
                         author=AUTHOR):
     magval = float(magval)
     if not creationTime: creationTime = sccore.Time.GMT()
     net = amp.waveformID().networkCode()
     sta = amp.waveformID().stationCode()
     mag = scdatamodel.StationMagnitude(parent.publicID() + '#staMag.' +
                                        amp.type() + '#' + net + '.' + sta)
     mag.setMagnitude(scdatamodel.RealQuantity(magval))
     mag.setType(amp.type())
     mag.setAmplitudeID(amp.publicID())
     mag.setWaveformID(amp.waveformID())
     self.addCreationInfo(mag, creationTime, agencyID, author)
     parent.add(mag)
     contrib = scdatamodel.StationMagnitudeContribution(
         mag.publicID(), 0, weight)
     parent.magnitude(0).add(contrib)
Exemple #6
0
 def addAmplitude(self,
                  ampval,
                  amptype,
                  snr,
                  pickid,
                  timeref,
                  starttime,
                  endtime,
                  creationTime=None,
                  agencyID=AGENCYID,
                  author=AUTHOR):
     ampval, snr, starttime, endtime = float(ampval), float(snr), float(
         starttime), float(endtime)
     if not creationTime: creationTime = sccore.Time.GMT()
     amp = scdatamodel.Amplitude(pickid + '.' + amptype)
     amp.setType(amptype)
     amp.setAmplitude(scdatamodel.RealQuantity(ampval))
     amp.setTimeWindow(scdatamodel.TimeWindow(timeref, starttime, endtime))
     amp.setSnr(snr)
     amp.setPickID(pickid)
     amp.setWaveformID(self.eparams.findPick(pickid).waveformID())
     self.addCreationInfo(amp, creationTime, agencyID, author)
     self.eparams.add(amp)
     return amp
Exemple #7
0
    def sh2proc(self, file):
        ep = DataModel.EventParameters()
        origin = DataModel.Origin.Create()
        event = DataModel.Event.Create()

        origin.setCreationInfo(DataModel.CreationInfo())
        origin.creationInfo().setCreationTime(Core.Time.GMT())

        originQuality = None
        originCE = None
        latFound = False
        lonFound = False
        depthError = None
        originComments = {}

        # variables, reset after 'end of phase'
        pick = None
        stationMag = None
        staCode = None
        compCode = None
        stationMagBB = None

        amplitudeDisp = None
        amplitudeVel = None
        amplitudeSNR = None
        amplitudeBB = None

        magnitudeMB = None
        magnitudeML = None
        magnitudeMS = None
        magnitudeBB = None

        km2degFac = 1.0 / Math.deg2km(1.0)

        # read file line by line, split key and value at colon
        iLine = 0
        for line in file:
            iLine += 1
            a = line.split(':', 1)
            key = a[0].strip()
            keyLower = key.lower()
            value = None

            # empty line
            if len(keyLower) == 0:
                continue

            # end of phase
            elif keyLower == '--- end of phase ---':
                if pick is None:
                    Logging.warning('Line %i: found empty phase block' % iLine)
                    continue

                if staCode is None or compCode is None:
                    Logging.warning('Line %i: end of phase, stream code '
                                    'incomplete' % iLine)
                    continue

                if staCode not in self.streams:
                    Logging.warning('Line %i: end of phase, station code %s '
                                    'not found in inventory' % (iLine, staCode))
                    continue

                if compCode not in self.streams[staCode]:
                    Logging.warning('Line %i: end of phase, component %s of '
                                    'station %s not found in inventory' % (
                                        iLine, compCode, staCode))
                    continue

                streamID = self.streams[staCode][compCode]

                pick.setWaveformID(streamID)
                ep.add(pick)

                arrival.setPickID(pick.publicID())
                arrival.setPhase(phase)
                origin.add(arrival)

                if amplitudeSNR is not None:
                    amplitudeSNR.setPickID(pick.publicID())
                    amplitudeSNR.setWaveformID(streamID)
                    ep.add(amplitudeSNR)

                if amplitudeBB is not None:
                    amplitudeBB.setPickID(pick.publicID())
                    amplitudeBB.setWaveformID(streamID)
                    ep.add(amplitudeBB)

                if stationMagBB is not None:
                    stationMagBB.setWaveformID(streamID)
                    origin.add(stationMagBB)
                    stationMagContrib = DataModel.StationMagnitudeContribution()
                    stationMagContrib.setStationMagnitudeID(
                        stationMagBB.publicID())
                    if magnitudeBB is None:
                        magnitudeBB = DataModel.Magnitude.Create()
                    magnitudeBB.add(stationMagContrib)

                if stationMag is not None:
                    if stationMag.type() in ['mb', 'ML'] and amplitudeDisp is not None:
                        amplitudeDisp.setPickID(pick.publicID())
                        amplitudeDisp.setWaveformID(streamID)
                        amplitudeDisp.setPeriod(
                            DataModel.RealQuantity(ampPeriod))
                        amplitudeDisp.setType(stationMag.type())
                        ep.add(amplitudeDisp)

                    if stationMag.type() in ['Ms(BB)'] and amplitudeVel is not None:
                        amplitudeVel.setPickID(pick.publicID())
                        amplitudeVel.setWaveformID(streamID)
                        amplitudeVel.setPeriod(
                            DataModel.RealQuantity(ampPeriod))
                        amplitudeVel.setType(stationMag.type())
                        ep.add(amplitudeVel)

                    stationMag.setWaveformID(streamID)
                    origin.add(stationMag)

                    stationMagContrib = DataModel.StationMagnitudeContribution()
                    stationMagContrib.setStationMagnitudeID(
                        stationMag.publicID())

                    magType = stationMag.type()
                    if magType == 'ML':
                        if magnitudeML is None:
                            magnitudeML = DataModel.Magnitude.Create()
                        magnitudeML.add(stationMagContrib)

                    elif magType == 'Ms(BB)':
                        if magnitudeMS is None:
                            magnitudeMS = DataModel.Magnitude.Create()
                        magnitudeMS.add(stationMagContrib)

                    elif magType == 'mb':
                        if magnitudeMB is None:
                            magnitudeMB = DataModel.Magnitude.Create()
                        magnitudeMB.add(stationMagContrib)

                pick = None
                staCode = None
                compCode = None
                stationMag = None
                stationMagBB = None
                amplitudeDisp = None
                amplitudeVel = None
                amplitudeSNR = None
                amplitudeBB = None
                continue

            # empty key
            elif len(a) == 1:
                Logging.warning('Line %i: key without value' % iLine)
                continue

            value = a[1].strip()
            if pick is None:
                pick = DataModel.Pick.Create()
                arrival = DataModel.Arrival()

            try:
                ##############################################################
                # station parameters

                # station code
                if keyLower == 'station code':
                    staCode = value

                # pick time
                elif keyLower == 'onset time':
                    pick.setTime(DataModel.TimeQuantity(self.parseTime(value)))

                # pick onset type
                elif keyLower == 'onset type':
                    found = False
                    for onset in [DataModel.EMERGENT, DataModel.IMPULSIVE,
                                  DataModel.QUESTIONABLE]:
                        if value == DataModel.EPickOnsetNames_name(onset):
                            pick.setOnset(onset)
                            found = True
                            break
                    if not found:
                        raise Exception('Unsupported onset value')

                # phase code
                elif keyLower == 'phase name':
                    phase = DataModel.Phase()
                    phase.setCode(value)
                    pick.setPhaseHint(phase)

                # event type
                elif keyLower == 'event type':
                    evttype = EventTypes[value]
                    event.setType(evttype)
                    originComments[key] = value

                # filter ID
                elif keyLower == 'applied filter':
                    pick.setFilterID(value)

                # channel code, prepended by configured Channel prefix if only
                # one character is found
                elif keyLower == 'component':
                    compCode = value

                # pick evaluation mode
                elif keyLower == 'pick type':
                    found = False
                    for mode in [DataModel.AUTOMATIC, DataModel.MANUAL]:
                        if value == DataModel.EEvaluationModeNames_name(mode):
                            pick.setEvaluationMode(mode)
                            found = True
                            break
                    if not found:
                        raise Exception('Unsupported evaluation mode value')

                # pick author
                elif keyLower == 'analyst':
                    creationInfo = DataModel.CreationInfo()
                    creationInfo.setAuthor(value)
                    pick.setCreationInfo(creationInfo)

                # pick polarity
                # isn't tested
                elif keyLower == 'sign':
                    if value == 'positive':
                        sign = '0'  # positive
                    elif value == 'negative':
                        sign = '1'  # negative
                    else:
                        sign = '2'  # unknown
                    pick.setPolarity(float(sign))

                # arrival weight
                elif keyLower == 'weight':
                    arrival.setWeight(float(value))

                # arrival azimuth
                elif keyLower == 'theo. azimuth (deg)':
                    arrival.setAzimuth(float(value))

                # pick theo backazimuth
                elif keyLower == 'theo. backazimuth (deg)':
                    if pick.slownessMethodID() == 'corrected':
                        Logging.debug('Line %i: ignoring parameter: %s' % (
                                      iLine, key))
                    else:
                        pick.setBackazimuth(
                            DataModel.RealQuantity(float(value)))
                        pick.setSlownessMethodID('theoretical')

                # pick beam slowness
                elif keyLower == 'beam-slowness (sec/deg)':
                    if pick.slownessMethodID() == 'corrected':
                        Logging.debug('Line %i: ignoring parameter: %s' % (
                                      iLine, key))
                    else:
                        pick.setHorizontalSlowness(
                            DataModel.RealQuantity(float(value)))
                        pick.setSlownessMethodID('Array Beam')

                # pick beam backazimuth
                elif keyLower == 'beam-azimuth (deg)':
                    if pick.slownessMethodID() == 'corrected':
                        Logging.debug('Line %i: ignoring parameter: %s' % (
                                      iLine, key))
                    else:
                        pick.setBackazimuth(
                            DataModel.RealQuantity(float(value)))

                # pick epi slowness
                elif keyLower == 'epi-slowness (sec/deg)':
                    pick.setHorizontalSlowness(
                        DataModel.RealQuantity(float(value)))
                    pick.setSlownessMethodID('corrected')

                # pick epi backazimuth
                elif keyLower == 'epi-azimuth (deg)':
                    pick.setBackazimuth(DataModel.RealQuantity(float(value)))

                # arrival distance degree
                elif keyLower == 'distance (deg)':
                    arrival.setDistance(float(value))

                # arrival distance km, recalculates for degree
                elif keyLower == 'distance (km)':
                    if isinstance(arrival.distance(), float):
                        Logging.debug('Line %i: ignoring parameter: %s' % (
                                      iLine-1, 'distance (deg)'))
                    arrival.setDistance(float(value) * km2degFac)

                # arrival time residual
                elif keyLower == 'residual time':
                    arrival.setTimeResidual(float(value))

                # amplitude snr
                elif keyLower == 'signal/noise':
                    amplitudeSNR = DataModel.Amplitude.Create()
                    amplitudeSNR.setType('SNR')
                    amplitudeSNR.setAmplitude(
                        DataModel.RealQuantity(float(value)))

                # amplitude period
                elif keyLower.startswith('period'):
                    ampPeriod = float(value)

                # amplitude value for displacement
                elif keyLower == 'amplitude (nm)':
                    amplitudeDisp = DataModel.Amplitude.Create()
                    amplitudeDisp.setAmplitude(
                        DataModel.RealQuantity(float(value)))
                    amplitudeDisp.setUnit('nm')

                # amplitude value for velocity
                elif keyLower.startswith('vel. amplitude'):
                    amplitudeVel = DataModel.Amplitude.Create()
                    amplitudeVel.setAmplitude(
                        DataModel.RealQuantity(float(value)))
                    amplitudeVel.setUnit('nm/s')

                elif keyLower == 'bb amplitude (nm/sec)':
                    amplitudeBB = DataModel.Amplitude.Create()
                    amplitudeBB.setAmplitude(
                        DataModel.RealQuantity(float(value)))
                    amplitudeBB.setType('mB')
                    amplitudeBB.setUnit('nm/s')
                    amplitudeBB.setPeriod(DataModel.RealQuantity(ampBBPeriod))

                elif keyLower == 'bb period (sec)':
                    ampBBPeriod = float(value)

                elif keyLower == 'broadband magnitude':
                    magType = self.parseMagType('bb')
                    stationMagBB = DataModel.StationMagnitude.Create()
                    stationMagBB.setMagnitude(
                        DataModel.RealQuantity(float(value)))
                    stationMagBB.setType(magType)
                    stationMagBB.setAmplitudeID(amplitudeBB.publicID())

                # ignored
                elif keyLower == 'quality number':
                    Logging.debug('Line %i: ignoring parameter: %s' % (
                                  iLine, key))

                # station magnitude value and type
                elif keyLower.startswith('magnitude '):
                    magType = self.parseMagType(key[10:])
                    stationMag = DataModel.StationMagnitude.Create()
                    stationMag.setMagnitude(
                        DataModel.RealQuantity(float(value)))

                    if len(magType) > 0:
                        stationMag.setType(magType)
                    if magType == 'mb':
                        stationMag.setAmplitudeID(amplitudeDisp.publicID())

                    elif magType == 'MS(BB)':
                        stationMag.setAmplitudeID(amplitudeVel.publicID())
                    else:
                        Logging.debug('Line %i: Magnitude Type not known %s.' % (
                                      iLine, magType))

                ###############################################################
                # origin parameters

                # event ID, added as origin comment later on
                elif keyLower == 'event id':
                    originComments[key] = value

                # magnitude value and type
                elif keyLower == 'mean bb magnitude':
                    magType = self.parseMagType('bb')
                    if magnitudeBB is None:
                        magnitudeBB = DataModel.Magnitude.Create()
                    magnitudeBB.setMagnitude(
                        DataModel.RealQuantity(float(value)))
                    magnitudeBB.setType(magType)

                elif keyLower.startswith('mean magnitude '):
                    magType = self.parseMagType(key[15:])

                    if magType == 'ML':
                        if magnitudeML is None:
                            magnitudeML = DataModel.Magnitude.Create()
                        magnitudeML.setMagnitude(
                            DataModel.RealQuantity(float(value)))
                        magnitudeML.setType(magType)

                    elif magType == 'Ms(BB)':
                        if magnitudeMS is None:
                            magnitudeMS = DataModel.Magnitude.Create()
                        magnitudeMS.setMagnitude(
                            DataModel.RealQuantity(float(value)))
                        magnitudeMS.setType(magType)

                    elif magType == 'mb':
                        if magnitudeMB is None:
                            magnitudeMB = DataModel.Magnitude.Create()
                        magnitudeMB.setMagnitude(
                            DataModel.RealQuantity(float(value)))
                        magnitudeMB.setType(magType)

                    else:
                        Logging.warning('Line %i: Magnitude type %s not defined yet.' % (
                                        iLine, magType))

                # latitude
                elif keyLower == 'latitude':
                    origin.latitude().setValue(float(value))
                    latFound = True
                elif keyLower == 'error in latitude (km)':
                    origin.latitude().setUncertainty(float(value))

                # longitude
                elif keyLower == 'longitude':
                    origin.longitude().setValue(float(value))
                    lonFound = True
                elif keyLower == 'error in longitude (km)':
                    origin.longitude().setUncertainty(float(value))

                # depth
                elif keyLower == 'depth (km)':
                    origin.setDepth(DataModel.RealQuantity(float(value)))
                    if depthError is not None:
                        origin.depth().setUncertainty(depthError)
                elif keyLower == 'depth type':
                    Logging.debug('Line %i: ignoring parameter: %s' % (
                                  iLine, key))
                elif keyLower == 'error in depth (km)':
                    depthError = float(value)
                    try:
                        origin.depth().setUncertainty(depthError)
                    except Core.ValueException:
                        pass

                # time
                elif keyLower == 'origin time':
                    origin.time().setValue(self.parseTime(value))
                elif keyLower == 'error in origin time':
                    origin.time().setUncertainty(float(value))

                # location method
                elif keyLower == 'location method':
                    origin.setMethodID(str(value))

                # region table, added as origin comment later on
                elif keyLower == 'region table':
                    originComments[key] = value

                # region table, added as origin comment later on
                elif keyLower == 'region id':
                    originComments[key] = value

                # source region, added as origin comment later on
                elif keyLower == 'source region':
                    originComments[key] = value

                # used station count
                elif keyLower == 'no. of stations used':
                    if originQuality is None:
                        originQuality = DataModel.OriginQuality()
                    originQuality.setUsedStationCount(int(value))

                # ignored
                elif keyLower == 'reference location name':
                    Logging.debug('Line %i: ignoring parameter: %s' % (
                                  iLine, key))

                # confidence ellipsoid major axis
                elif keyLower == 'error ellipse major':
                    if originCE is None:
                        originCE = DataModel.ConfidenceEllipsoid()
                    originCE.setSemiMajorAxisLength(float(value))

                # confidence ellipsoid minor axis
                elif keyLower == 'error ellipse minor':
                    if originCE is None:
                        originCE = DataModel.ConfidenceEllipsoid()
                    originCE.setSemiMinorAxisLength(float(value))

                # confidence ellipsoid rotation
                elif keyLower == 'error ellipse strike':
                    if originCE is None:
                        originCE = DataModel.ConfidenceEllipsoid()
                    originCE.setMajorAxisRotation(float(value))

                # azimuthal gap
                elif keyLower == 'max azimuthal gap (deg)':
                    if originQuality is None:
                        originQuality = DataModel.OriginQuality()
                    originQuality.setAzimuthalGap(float(value))

                # creation info author
                elif keyLower == 'author':
                    origin.creationInfo().setAuthor(value)

                # creation info agency
                elif keyLower == 'source of information':
                    origin.creationInfo().setAgencyID(value)

                # earth model id
                elif keyLower == 'velocity model':
                    origin.setEarthModelID(value)

                # standard error
                elif keyLower == 'rms of residuals (sec)':
                    if originQuality is None:
                        originQuality = DataModel.OriginQuality()
                    originQuality.setStandardError(float(value))

                # ignored
                elif keyLower == 'phase flags':
                    Logging.debug('Line %i: ignoring parameter: %s' % (
                                  iLine, key))

                # ignored
                elif keyLower == 'location input params':
                    Logging.debug('Line %i: ignoring parameter: %s' % (
                                  iLine, key))

                # missing keys
                elif keyLower == 'ampl&period source':
                    Logging.debug('Line %i: ignoring parameter: %s' % (
                                  iLine, key))

                elif keyLower == 'location quality':
                    Logging.debug('Line %i: ignoring parameter: %s' % (
                                  iLine, key))

                elif keyLower == 'reference latitude':
                    Logging.debug('Line %i: ignoring parameter: %s' % (
                                  iLine, key))

                elif keyLower == 'reference longitude':
                    Logging.debug('Line %i: ignoring parameter: %s' % (
                                  iLine, key))

                elif keyLower.startswith('amplitude time'):
                    Logging.debug('Line %i: ignoring parameter: %s' % (
                                  iLine, key))

                # unknown key
                else:
                    Logging.warning('Line %i: ignoring unknown parameter: %s'
                                    % (iLine, key))

            except ValueError as ve:
                Logging.warning('Line %i: can not parse %s value' % (
                                iLine, key))
            except Exception:
                Logging.error('Line %i: %s' % (iLine,
                                               str(traceback.format_exc())))
                return None

        # check
        if not latFound:
            Logging.warning('could not add origin, missing latitude parameter')
        elif not lonFound:
            Logging.warning(
                'could not add origin, missing longitude parameter')
        elif not origin.time().value().valid():
            Logging.warning(
                'could not add origin, missing origin time parameter')
        else:
            if magnitudeMB is not None:
                origin.add(magnitudeMB)
            if magnitudeML is not None:
                origin.add(magnitudeML)
            if magnitudeMS is not None:
                origin.add(magnitudeMS)
            if magnitudeBB is not None:
                origin.add(magnitudeBB)

            ep.add(event)
            ep.add(origin)

            if originQuality is not None:
                origin.setQuality(originQuality)

            if originCE is not None:
                uncertainty = DataModel.OriginUncertainty()
                uncertainty.setConfidenceEllipsoid(originCE)
                origin.setUncertainty(uncertainty)

            for k, v in originComments.items():
                comment = DataModel.Comment()
                comment.setId(k)
                comment.setText(v)
                origin.add(comment)

        return ep
Exemple #8
0
    def sh2proc(self, file):
        ep = DataModel.EventParameters()
        magnitude = DataModel.Magnitude.Create()
        origin = DataModel.Origin.Create()

        origin.setCreationInfo(DataModel.CreationInfo())
        origin.creationInfo().setCreationTime(Core.Time.GMT())

        originQuality = None
        originCE = None
        latFound = False
        lonFound = False
        depthError = None
        originComments = {}

        # phase variables, reset after 'end of phase'
        pick = None
        stationMag = None
        staCode = None
        compCode = None

        # read file line by line, split key and value at colon
        iLine = 0
        for line in file:
            iLine += 1
            a = line.split(':', 1)
            key = a[0].strip()
            keyLower = key.lower()
            value = None

            # empty line
            if len(keyLower) == 0:
                continue

            # end of phase
            elif keyLower == '--- end of phase ---':
                if pick is None:
                    Logging.warning('Line %i: found empty phase block' % iLine)
                    continue

                if staCode is None or compCode is None:
                    Logging.warning('Line %i: end of phase, stream code ' \
                                    'incomplete' % iLine)
                    continue

                if not self.streams.has_key(staCode):
                    Logging.warning('Line %i: end of phase, station code %s ' \
                                    'not found in inventory' % (iLine, staCode))
                    continue

                if not self.streams[staCode].has_key(compCode):
                    Logging.warning('Line %i: end of phase, component %s of ' \
                                    'station %s not found in inventory' % (
                                    iLine, compCode, staCode))
                    continue

                streamID = self.streams[staCode][compCode]

                pick.setWaveformID(streamID)
                ep.add(pick)

                arrival.setPickID(pick.publicID())
                origin.add(arrival)

                amplitude.setPickID(pick.publicID())
                ep.add(amplitude)

                if stationMag is not None:
                    stationMag.setWaveformID(streamID)
                    origin.add(stationMag)

                    stationMagContrib = DataModel.StationMagnitudeContribution(
                    )
                    stationMagContrib.setStationMagnitudeID(
                        stationMag.publicID())
                    magnitude.add(stationMagContrib)

                pick = None
                staCode = None
                compCode = None
                stationMag = None
                continue

            # empty key
            elif len(a) == 1:
                Logging.warning('Line %i: key without value' % iLine)
                continue

            value = a[1].strip()

            if pick is None:
                pick = DataModel.Pick.Create()
                arrival = DataModel.Arrival()
                amplitude = DataModel.Amplitude.Create()

            try:
                ##############################################################
                # station parameters

                # station code
                if keyLower == 'station code':
                    staCode = value

                # pick time
                elif keyLower == 'onset time':
                    pick.setTime(DataModel.TimeQuantity(self.parseTime(value)))

                # pick onset type
                elif keyLower == 'onset type':
                    found = False
                    for onset in [
                            DataModel.EMERGENT, DataModel.IMPULSIVE,
                            DataModel.QUESTIONABLE
                    ]:
                        if value == DataModel.EPickOnsetNames_name(onset):
                            pick.setOnset(onset)
                            found = True
                            break
                    if not found:
                        raise Exception('Unsupported onset value')

                # phase code
                elif keyLower == 'phase name':
                    phase = DataModel.Phase()
                    phase.setCode(value)
                    pick.setPhaseHint(phase)
                    arrival.setPhase(phase)

                # event type, added as origin comment later on
                elif keyLower == 'event type':
                    originComments[key] = value

                # filter ID
                elif keyLower == 'applied filter':
                    pick.setFilterID(value)

                # channel code, prepended by configured Channel prefix if only
                # one character is found
                elif keyLower == 'component':
                    compCode = value

                # pick evaluation mode
                elif keyLower == 'pick type':
                    found = False
                    for mode in [DataModel.AUTOMATIC, DataModel.MANUAL]:
                        if value == DataModel.EEvaluationModeNames_name(mode):
                            pick.setEvaluationMode(mode)
                            found = True
                            break
                    if not found:
                        raise Exception('Unsupported evaluation mode value')

                # arrival weight
                elif keyLower == 'weight':
                    arrival.setWeight(float(value))

                # arrival azimuth
                elif keyLower == 'theo. azimuth (deg)':
                    arrival.setAzimuth(float(value))

                # arrival backazimuth
                elif keyLower == 'theo. backazimuth (deg)':
                    pick.setBackazimuth(DataModel.RealQuantity(float(value)))

                # arrival distance
                elif keyLower == 'distance (deg)':
                    arrival.setDistance(float(value))

                # ignored
                elif keyLower == 'distance (km)':
                    Logging.debug('Line %i: ignoring parameter: %s' %
                                  (iLine, key))

                # arrival time residual
                elif keyLower == 'residual time':
                    arrival.setTimeResidual(float(value))

                # ignored
                elif keyLower == 'quality number':
                    Logging.debug('Line %i: ignoring parameter: %s' %
                                  (iLine, key))

                # station magnitude value and type
                elif keyLower.startswith('magnitude '):
                    stationMag = DataModel.StationMagnitude.Create()
                    stationMag.setAmplitudeID(amplitude.publicID())
                    stationMag.setMagnitude(
                        DataModel.RealQuantity(float(value)))
                    magType = self.parseMagType(key[10:])
                    if len(magType) > 0:
                        stationMag.setType(magType)
                        amplitude.setType(magType)

                ###############################################################
                # origin parameters

                # event ID, added as origin comment later on
                elif keyLower == 'event id':
                    originComments[key] = value

                # magnitude value and type
                elif keyLower.startswith('mean magnitude '):
                    magnitude.setMagnitude(DataModel.RealQuantity(
                        float(value)))
                    magType = self.parseMagType(key[15:])
                    if len(magType) > 0:
                        magnitude.setType(magType)

                # latitude
                elif keyLower == 'latitude':
                    origin.latitude().setValue(float(value))
                    latFound = True
                elif keyLower == 'error in latitude (km)':
                    origin.latitude().setUncertainty(float(value))

                # longitude
                elif keyLower == 'longitude':
                    origin.longitude().setValue(float(value))
                    lonFound = True
                elif keyLower == 'error in longitude (km)':
                    origin.longitude().setUncertainty(float(value))

                # depth
                elif keyLower == 'depth (km)':
                    origin.setDepth(DataModel.RealQuantity(float(value)))
                    if depthError is not None:
                        origin.depth().setUncertainty(depthError)
                elif keyLower == 'depth type':
                    Logging.debug('Line %i: ignoring parameter: %s' %
                                  (iLine, key))
                elif keyLower == 'error in depth (km)':
                    depthError = float(value)
                    try:
                        origin.depth().setUncertainty(depthError)
                    except Core.ValueException:
                        pass

                # time
                elif keyLower == 'origin time':
                    origin.time().setValue(self.parseTime(value))
                elif keyLower == 'error in origin time':
                    origin.time().setUncertainty(float(value))

                # region table, added as origin comment later on
                elif keyLower == 'region table':
                    originComments[key] = value

                # region table, added as origin comment later on
                elif keyLower == 'region id':
                    originComments[key] = value

                # source region, added as origin comment later on
                elif keyLower == 'source region':
                    originComments[key] = value

                # used station count
                elif keyLower == 'no. of stations used':
                    if originQuality is None:
                        originQuality = DataModel.OriginQuality()
                    originQuality.setUsedStationCount(int(value))

                # ignored
                elif keyLower == 'reference location name':
                    Logging.debug('Line %i: ignoring parameter: %s' %
                                  (iLine, key))

                # confidence ellipsoid major axis
                elif keyLower == 'error ellipse major':
                    if originCE is None:
                        originCE = DataModel.ConfidenceEllipsoid()
                    originCE.setSemiMajorAxisLength(float(value))

                # confidence ellipsoid minor axis
                elif keyLower == 'error ellipse minor':
                    if originCE is None:
                        originCE = DataModel.ConfidenceEllipsoid()
                    originCE.setSemiMinorAxisLength(float(value))

                # confidence ellipsoid rotation
                elif keyLower == 'error ellipse strike':
                    if originCE is None:
                        originCE = DataModel.ConfidenceEllipsoid()
                    originCE.setMajorAxisRotation(float(value))

                # azimuthal gap
                elif keyLower == 'max azimuthal gap (deg)':
                    if originQuality is None:
                        originQuality = DataModel.OriginQuality()
                    originQuality.setAzimuthalGap(float(value))

                # creation info author
                elif keyLower == 'author':
                    origin.creationInfo().setAuthor(value)

                # creation info agency
                elif keyLower == 'agency':
                    origin.creationInfo().setAgencyID(value)

                # earth model id
                elif keyLower == 'velocity model':
                    origin.setEarthModelID(value)

                # standard error
                elif keyLower == 'rms of residuals (sec)':
                    if originQuality is None:
                        originQuality = DataModel.OriginQuality()
                    originQuality.setStandardError(float(value))

                # ignored
                elif keyLower == 'phase flags':
                    Logging.debug('Line %i: ignoring parameter: %s' %
                                  (iLine, key))

                # ignored
                elif keyLower == 'location input params':
                    Logging.debug('Line %i: ignoring parameter: %s' %
                                  (iLine, key))

                # unknown key
                else:
                    Logging.warning('Line %i: ignoring unknown parameter: %s' \
                                    % (iLine, key))

            except ValueError, ve:
                Logging.warning('Line %i: can not parse %s value' %
                                (iLine, key))
            except Exception:
                Logging.error('Line %i: %s' %
                              (iLine, str(traceback.format_exc())))
                return None
def createObjects(item: WPhaseResult, agency, evid=None, with_notifiers=False):
    """Convert a WPhaseResult to seiscomp3.DataModel objects, optionally sending
    Notifier events to messaging.

    :param WPhaseResult item:
        Result of a W-Phase inversion.
    :param bool with_notifiers:
        If true, seiscomp3.DataModel.Notifier instances will be created linking
        the FocalMechanism and derived Origin to the triggering event.
    :rtype: dict
    :return:
        A dictionary with keys focalMechanism, derivedOrigin, momentMagnitude
        (mapped to seiscomp3.DataModel objects), and optionally notifiers
        (mapped to a list of Notifiers)."""
    mt = item.MomentTensor
    preferredOL = item.OL3 or item.OL2
    if not (mt and preferredOL):
        raise ValueError(
            "W-Phase result contains no MomentTensor to convert/send!")

    # get current time in UTC
    time = Core.Time.GMT()

    # create creation info
    ci = DM.CreationInfo()
    ci.setCreationTime(time)
    ci.setAgencyID(agency)
    ci.setAuthor(charstar(mt.auth))

    originTime = DM.TimeQuantity(datetime_to_seiscomp(item.Event.time))

    # fill derived origin
    derivedOrigin = DM.Origin.Create()
    derivedOrigin.setCreationInfo(ci)
    derivedOrigin.setTime(originTime)
    derivedOrigin.setLatitude(DM.RealQuantity(mt.drlat))
    derivedOrigin.setLongitude(DM.RealQuantity(mt.drlon))
    derivedOrigin.setDepth(DM.RealQuantity(mt.drdepth))
    derivedOrigin.setEvaluationMode(DM.AUTOMATIC)
    derivedOrigin.setEvaluationStatus(DM.CONFIRMED)

    originQuality = DM.OriginQuality()
    if item.QualityParams is not None:
        try:
            originQuality.setUsedPhaseCount(
                item.QualityParams.number_of_channels)
        except Exception:
            pass

        try:
            originQuality.setUsedStationCount(
                item.QualityParams.number_of_stations)
        except Exception:
            pass

    derivedOrigin.setQuality(originQuality)

    if item.Centroid:
        derivedOrigin.setType(DM.CENTROID)
    else:
        derivedOrigin.setType(DM.HYPOCENTER)

    # fill magnitude
    try:
        mag = DM.Magnitude.Create()
        mag.setMagnitude(DM.RealQuantity(mt.drmag))
        mag.setCreationInfo(ci)
        mag.setOriginID(derivedOrigin.publicID())
        mag.setType(charstar(mt.drmagt))
        if item.QualityParams:
            mag.setStationCount(item.QualityParams.number_of_stations)
        mag.setMethodID("wphase")
    except Exception as e:
        logger.error("Failed to configure magnitude: {}".format(e))

    ## Set FocalMechanism
    nodalPlanes = DM.NodalPlanes()
    np1 = DM.NodalPlane()
    np2 = DM.NodalPlane()

    np1.setStrike(DM.RealQuantity(mt.str1))
    np1.setDip(DM.RealQuantity(mt.dip1))
    np1.setRake(DM.RealQuantity(mt.rake1))

    np2.setStrike(DM.RealQuantity(mt.str2))
    np2.setDip(DM.RealQuantity(mt.dip2))
    np2.setRake(DM.RealQuantity(mt.rake2))

    nodalPlanes.setNodalPlane1(np1)
    nodalPlanes.setNodalPlane2(np2)

    fm = DM.FocalMechanism.Create()
    fm.setNodalPlanes(nodalPlanes)
    fm.setCreationInfo(ci)
    fm.setMethodID("wphase")
    fm.setEvaluationMode(DM.AUTOMATIC)

    misfit = preferredOL.misfit / 100.0
    fm.setMisfit(misfit)
    if item.QualityParams:
        fm.setStationPolarityCount(item.QualityParams.number_of_channels)
        try:
            fm.setAzimuthalGap(item.QualityParams.azimuthal_gap)
        except Exception:
            pass

    # TODO set axis

    # fill tensor
    tensor = DM.Tensor()

    try:
        tensor.setMtp(DM.RealQuantity(fm.tmtp))
    except Exception:
        pass

    try:
        tensor.setMtt(DM.RealQuantity(fm.tmtt))
    except Exception:
        pass

    try:
        tensor.setMrt(DM.RealQuantity(fm.tmrt))
    except Exception:
        pass

    try:
        tensor.setMrr(DM.RealQuantity(fm.tmrr))
    except Exception:
        pass

    try:
        tensor.setMrp(DM.RealQuantity(fm.tmrp))
    except Exception:
        pass

    try:
        tensor.setMpp(DM.RealQuantity(fm.tmpp))
    except Exception:
        pass

    # fill moment tensor object
    mt = DM.MomentTensor.Create()
    mt.setTensor(tensor)
    mt.setCreationInfo(ci)
    mt.setDerivedOriginID(derivedOrigin.publicID())
    mt.setMethodID("wphase")

    try:
        mt.setClvd(fm.clvd)
    except Exception:
        pass

    try:
        mt.setDoubleCouple(fm.dc)
    except Exception:
        pass

    try:
        mt.setMomentMagnitudeID(mag.publicID())
    except Exception:
        pass

    # Since we don't want to overwrite the event data itself, but we do
    # want to explicitly associate our data to the correct event, we have
    # to manually create Notifiers for these associations.
    oRef = DM.OriginReference()
    oRef.setOriginID(derivedOrigin.publicID())

    fmRef = DM.FocalMechanismReference()
    fmRef.setFocalMechanismID(fm.publicID())
    if with_notifiers and evid:
        notifiers = [
            # TODO: are these two actually valid? Origins/FMs are associated to events
            # by references, but are not children thereof!
            DM.Notifier.Create(evid, DM.OP_ADD, derivedOrigin),
            DM.Notifier.Create(evid, DM.OP_ADD, fm),
            # I *think* we only actually need these two.
            DM.Notifier.Create(evid, DM.OP_ADD, oRef),
            DM.Notifier.Create(evid, DM.OP_ADD, fmRef),
        ]

    # Adding these seems to *immediately* queue up the notifications; so we
    # must do this *after* notifying the origin/FM so that scmaster
    # processes everything in the correct order.
    derivedOrigin.add(mag)
    fm.add(mt)

    ret = {
        "derivedOrigin": derivedOrigin,
        "momentMagnitude": mag,
        "focalMechanism": fm,
    }
    if with_notifiers:
        ret["notifiers"] = notifiers
    return ret