Beispiel #1
0
 def _getDistancesArrivalsSorted(self, org):
     # sort arrival list by distance
     dist_arr = []
     if self.distInKM:
         from seiscomp3 import Math
         for i in xrange(org.arrivalCount()):
             arr = org.arrival(i)
             dist_arr.append((Math.deg2km(arr.distance()), arr))
     else:
         for i in xrange(org.arrivalCount()):
             arr = org.arrival(i)
             dist_arr.append((arr.distance(), arr))
     dist_arr.sort()
     return dist_arr
Beispiel #2
0
 def _getDistancesArrivalsSorted(self, org):
     # sort arrival list by distance
     dist_arr = []
     if self.distInKM:
         from seiscomp3 import Math
         for i in xrange(org.arrivalCount()):
             arr = org.arrival(i)
             dist_arr.append((Math.deg2km(arr.distance()), arr))
     else:
         for i in xrange(org.arrivalCount()):
             arr = org.arrival(i)
             dist_arr.append((arr.distance(), arr))
     dist_arr.sort()
     return dist_arr
Beispiel #3
0
 def _getDistancesArrivalsSorted(self, org):
     # sort arrival list by distance
     dist_arr = []
     if self.distInKM:
         from seiscomp3 import Math
         for i in range(org.arrivalCount()):
             arr = org.arrival(i)
             try:
                 dist_arr.append((Math.deg2km(arr.distance()), arr))
             except ValueError:
                 pass
     else:
         for i in range(org.arrivalCount()):
             arr = org.arrival(i)
             try:
                 dist_arr.append((arr.distance(), arr))
             except ValueError:
                 pass
     return sorted(dist_arr, key=lambda a: a[0])
Beispiel #4
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