Exemplo n.º 1
0
    def run(self):
        """ Things to do:
        
        * load event
        * load preferred origin without arrivals
        * load at least the preferred magnitude if available, all magnitudes if requested
        * load focal mechanism incl. moment tensor depending on availability, incl. Mw from derived origin
        """
        evid = self.commandline().optionString("event")

        # Load event and preferred origin. This is the minimum
        # required info and if it can't be loaded, give up.
        event = self._loadEvent(evid)
        if event is None:
            raise ValueError, "unknown event '" + evid + "'"
#       preferredOrigin = self._loadOrigin(event.preferredOriginID())
        preferredOrigin = self.query().getObject(DataModel.Origin.TypeInfo(),
                                                 event.preferredOriginID())
        preferredOrigin = DataModel.Origin.Cast(preferredOrigin)
        if preferredOrigin is None:
            raise ValueError, "unknown origin '" + event.preferredOriginID(
            ) + "'"
        # take care of origin references and leave just one for the preferred origin
        while (event.originReferenceCount() > 0):
            event.removeOriginReference(0)
        if preferredOrigin:
            event.add(DataModel.OriginReference(preferredOrigin.publicID()))
        if self.commandline().hasOption("comments"):
            self.query().loadComments(preferredOrigin)

        # load all magnitudes for preferredOrigin
        if self.commandline().hasOption("all-magnitudes"):
            self.query().loadMagnitudes(preferredOrigin)
            magnitudes = [
                preferredOrigin.magnitude(i)
                for i in range(preferredOrigin.magnitudeCount())
            ]
        else:
            magnitudes = []
        if event.preferredMagnitudeID():
            # try to load from memory
            for mag in magnitudes:
                if mag.publicID() == event.preferredMagnitudeID():
                    preferredMagnitude = mag
                    break


#           preferredMagnitude = DataModel.Magnitude.Find(event.preferredMagnitudeID())
            else:
                # try to load it from database
                preferredMagnitude = self._loadMagnitude(
                    event.preferredMagnitudeID())
        else:
            preferredMagnitude = None

        # try to load focal mechanism, moment tensor, moment magnitude and related origins
        momentTensor = momentMagnitude = derivedOrigin = triggeringOrigin = None  # default
        focalMechanism = self._loadFocalMechanism(
            event.preferredFocalMechanismID())
        if focalMechanism:
            if focalMechanism.triggeringOriginID():
                if event.preferredOriginID(
                ) == focalMechanism.triggeringOriginID():
                    triggeringOrigin = preferredOrigin
                else:
                    triggeringOrigin = self.query().getObject(
                        DataModel.Origin.TypeInfo(),
                        focalMechanism.triggeringOriginID())
                    triggeringOrigin = DataModel.Origin.Cast(triggeringOrigin)

            if focalMechanism.momentTensorCount() > 0:
                momentTensor = focalMechanism.momentTensor(
                    0)  # FIXME What if there is more than one MT?
                if momentTensor.derivedOriginID():
                    derivedOrigin = self.query().getObject(
                        DataModel.Origin.TypeInfo(),
                        momentTensor.derivedOriginID())
                    derivedOrigin = DataModel.Origin.Cast(derivedOrigin)
                if momentTensor.momentMagnitudeID():
                    if momentTensor.momentMagnitudeID(
                    ) == event.preferredMagnitudeID():
                        momentMagnitude = preferredMagnitude
                    else:
                        momentMagnitude = self._loadMagnitude(
                            momentTensor.momentMagnitudeID())

            # take care of FocalMechanism and related references
            if derivedOrigin:
                event.add(DataModel.OriginReference(derivedOrigin.publicID()))
            if triggeringOrigin:
                if event.preferredOriginID() != triggeringOrigin.publicID():
                    event.add(
                        DataModel.OriginReference(triggeringOrigin.publicID()))
            while (event.focalMechanismReferenceCount() > 0):
                event.removeFocalMechanismReference(0)
            if focalMechanism:
                event.add(
                    DataModel.FocalMechanismReference(
                        focalMechanism.publicID()))
                self._removeCommentsIfRequested(focalMechanism)

        # strip creation info
        if not self.commandline().hasOption("include-full-creation-info"):
            self._stripCreationInfo(event)
            if focalMechanism:
                self._stripCreationInfo(focalMechanism)
                for i in xrange(focalMechanism.momentTensorCount()):
                    self._stripCreationInfo(focalMechanism.momentTensor(i))
            for org in [preferredOrigin, triggeringOrigin, derivedOrigin]:
                if org is not None:
                    self._stripCreationInfo(org)
                    for i in xrange(org.magnitudeCount()):
                        self._stripCreationInfo(org.magnitude(i))

        # populate EventParameters instance
        ep = DataModel.EventParameters()
        ep.add(event)
        if preferredMagnitude and preferredMagnitude is not momentMagnitude:
            preferredOrigin.add(preferredMagnitude)
        ep.add(preferredOrigin)
        if focalMechanism:
            if triggeringOrigin:
                if triggeringOrigin is not preferredOrigin:
                    ep.add(triggeringOrigin)
            if derivedOrigin:
                if momentMagnitude:
                    derivedOrigin.add(momentMagnitude)
                ep.add(derivedOrigin)
            ep.add(focalMechanism)

        # finally dump event parameters as formatted XML archive to stdout
        ar = IO.XMLArchive()
        ar.setFormattedOutput(True)
        ar.create("-")
        ar.writeObject(ep)
        ar.close()

        del ep
Exemplo n.º 2
0
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