def addEvent(self, Eid, origins=[], creationTime=None, agencyID=AGENCYID, author=AUTHOR): if not creationTime: creationTime = sccore.Time.GMT() new = False event = self.eparams.findEvent(Eid) if not event: event = scdatamodel.Event(Eid) self.addCreationInfo(event, creationTime, agencyID, author) self.eparams.add(event) new = True event.creationInfo().setModificationTime(creationTime) for origin in origins: event.add(scdatamodel.OriginReference(origin.publicID())) if new: event.setPreferredOriginID(origin.publicID()) if origin.magnitudeCount(): magid = origin.magnitude(origin.magnitudeCount() - 1).publicID() if not self.eparams.findOrigin(event.preferredOriginID( )).evaluationStatus() == scdatamodel.REPORTED: event.setPreferredMagnitudeID(magid) event.setPreferredOriginID(origin.publicID()) if not int(Eid) < 0: self.eparams.add(event)
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
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