def event_to_quakeml(event, filename): """ Write one of those events to QuakeML. """ # Create all objects. cat = Catalog() ev = Event() org = Origin() mag = Magnitude() fm = FocalMechanism() mt = MomentTensor() t = Tensor() # Link them together. cat.append(ev) ev.origins.append(org) ev.magnitudes.append(mag) ev.focal_mechanisms.append(fm) fm.moment_tensor = mt mt.tensor = t # Fill values ev.resource_id = "smi:inversion/%s" % str(event["identifier"]) org.time = event["time"] org.longitude = event["longitude"] org.latitude = event["latitude"] org.depth = event["depth_in_km"] * 1000 mag.mag = event["Mw"] mag.magnitude_type = "Mw" t.m_rr = event["Mrr"] t.m_tt = event["Mpp"] t.m_pp = event["Mtt"] t.m_rt = event["Mrt"] t.m_rp = event["Mrp"] t.m_tp = event["Mtp"] cat.write(filename, format="quakeml")
def par2quakeml(Par_filename, QuakeML_filename, rotation_axis=[0.0, 1.0, 0.0], rotation_angle=-57.5, origin_time="2000-01-01 00:00:00.0", event_type="other event"): # initialise event ev = Event() # open and read Par file fid = open(Par_filename, 'r') fid.readline() fid.readline() fid.readline() fid.readline() lat_old = 90.0 - float(fid.readline().strip().split()[0]) lon_old = float(fid.readline().strip().split()[0]) depth = float(fid.readline().strip().split()[0]) fid.readline() Mtt_old = float(fid.readline().strip().split()[0]) Mpp_old = float(fid.readline().strip().split()[0]) Mrr_old = float(fid.readline().strip().split()[0]) Mtp_old = float(fid.readline().strip().split()[0]) Mtr_old = float(fid.readline().strip().split()[0]) Mpr_old = float(fid.readline().strip().split()[0]) # rotate event into physical domain lat, lon = rot.rotate_lat_lon(lat_old, lon_old, rotation_axis, rotation_angle) Mrr, Mtt, Mpp, Mtr, Mpr, Mtp = rot.rotate_moment_tensor( Mrr_old, Mtt_old, Mpp_old, Mtr_old, Mpr_old, Mtp_old, lat_old, lon_old, rotation_axis, rotation_angle) # populate event origin data ev.event_type = event_type ev_origin = Origin() ev_origin.time = UTCDateTime(origin_time) ev_origin.latitude = lat ev_origin.longitude = lon ev_origin.depth = depth ev.origins.append(ev_origin) # populte event moment tensor ev_tensor = Tensor() ev_tensor.m_rr = Mrr ev_tensor.m_tt = Mtt ev_tensor.m_pp = Mpp ev_tensor.m_rt = Mtr ev_tensor.m_rp = Mpr ev_tensor.m_tp = Mtp ev_momenttensor = MomentTensor() ev_momenttensor.tensor = ev_tensor ev_momenttensor.scalar_moment = np.sqrt(Mrr**2 + Mtt**2 + Mpp**2 + Mtr**2 + Mpr**2 + Mtp**2) ev_focalmechanism = FocalMechanism() ev_focalmechanism.moment_tensor = ev_momenttensor ev_focalmechanism.nodal_planes = NodalPlanes().setdefault(0, 0) ev.focal_mechanisms.append(ev_focalmechanism) # populate event magnitude ev_magnitude = Magnitude() ev_magnitude.mag = 0.667 * (np.log10(ev_momenttensor.scalar_moment) - 9.1) ev_magnitude.magnitude_type = 'Mw' ev.magnitudes.append(ev_magnitude) # write QuakeML file cat = Catalog() cat.append(ev) cat.write(QuakeML_filename, format="quakeml") # clean up fid.close()
def par2quakeml(Par_filename, QuakeML_filename, rotation_axis=[0.0, 1.0, 0.0], rotation_angle=-57.5, origin_time="2000-01-01 00:00:00.0", event_type="other event"): # initialise event ev = Event() # open and read Par file fid = open(Par_filename, 'r') fid.readline() fid.readline() fid.readline() fid.readline() lat_old = 90.0 - float(fid.readline().strip().split()[0]) lon_old = float(fid.readline().strip().split()[0]) depth = float(fid.readline().strip().split()[0]) fid.readline() Mtt_old = float(fid.readline().strip().split()[0]) Mpp_old = float(fid.readline().strip().split()[0]) Mrr_old = float(fid.readline().strip().split()[0]) Mtp_old = float(fid.readline().strip().split()[0]) Mtr_old = float(fid.readline().strip().split()[0]) Mpr_old = float(fid.readline().strip().split()[0]) # rotate event into physical domain lat, lon = rot.rotate_lat_lon(lat_old, lon_old, rotation_axis, rotation_angle) Mrr, Mtt, Mpp, Mtr, Mpr, Mtp = rot.rotate_moment_tensor( Mrr_old, Mtt_old, Mpp_old, Mtr_old, Mpr_old, Mtp_old, lat_old, lon_old, rotation_axis, rotation_angle) # populate event origin data ev.event_type = event_type ev_origin = Origin() ev_origin.time = UTCDateTime(origin_time) ev_origin.latitude = lat ev_origin.longitude = lon ev_origin.depth = depth ev.origins.append(ev_origin) # populte event moment tensor ev_tensor = Tensor() ev_tensor.m_rr = Mrr ev_tensor.m_tt = Mtt ev_tensor.m_pp = Mpp ev_tensor.m_rt = Mtr ev_tensor.m_rp = Mpr ev_tensor.m_tp = Mtp ev_momenttensor = MomentTensor() ev_momenttensor.tensor = ev_tensor ev_momenttensor.scalar_moment = np.sqrt(Mrr ** 2 + Mtt ** 2 + Mpp ** 2 + Mtr ** 2 + Mpr ** 2 + Mtp ** 2) ev_focalmechanism = FocalMechanism() ev_focalmechanism.moment_tensor = ev_momenttensor ev_focalmechanism.nodal_planes = NodalPlanes().setdefault(0, 0) ev.focal_mechanisms.append(ev_focalmechanism) # populate event magnitude ev_magnitude = Magnitude() ev_magnitude.mag = 0.667 * (np.log10(ev_momenttensor.scalar_moment) - 9.1) ev_magnitude.magnitude_type = 'Mw' ev.magnitudes.append(ev_magnitude) # write QuakeML file cat = Catalog() cat.append(ev) cat.write(QuakeML_filename, format="quakeml") # clean up fid.close()
def build(self): """ Build an obspy moment tensor focal mech event This makes the tensor output into an Event containing: 1) a FocalMechanism with a MomentTensor, NodalPlanes, and PrincipalAxes 2) a Magnitude of the Mw from the Tensor Which is what we want for outputting QuakeML using the (slightly modified) obspy code. Input ----- filehandle => open file OR str from filehandle.read() Output ------ event => instance of Event() class as described above """ p = self.parser event = Event(event_type='earthquake') origin = Origin() focal_mech = FocalMechanism() nodal_planes = NodalPlanes() moment_tensor = MomentTensor() principal_ax = PrincipalAxes() magnitude = Magnitude() data_used = DataUsed() creation_info = CreationInfo(agency_id='NN') ev_mode = 'automatic' ev_stat = 'preliminary' evid = None orid = None # Parse the entire file line by line. for n,l in enumerate(p.line): if 'REVIEWED BY NSL STAFF' in l: ev_mode = 'manual' ev_stat = 'reviewed' if 'Event ID' in l: evid = p._id(n) if 'Origin ID' in l: orid = p._id(n) if 'Ichinose' in l: moment_tensor.category = 'regional' if re.match(r'^\d{4}\/\d{2}\/\d{2}', l): ev = p._event_info(n) if 'Depth' in l: derived_depth = p._depth(n) if 'Mw' in l: magnitude.mag = p._mw(n) magnitude.magnitude_type = 'Mw' if 'Mo' in l and 'dyne' in l: moment_tensor.scalar_moment = p._mo(n) if 'Percent Double Couple' in l: moment_tensor.double_couple = p._percent(n) if 'Percent CLVD' in l: moment_tensor.clvd = p._percent(n) if 'Epsilon' in l: moment_tensor.variance = p._epsilon(n) if 'Percent Variance Reduction' in l: moment_tensor.variance_reduction = p._percent(n) if 'Major Double Couple' in l and 'strike' in p.line[n+1]: np = p._double_couple(n) nodal_planes.nodal_plane_1 = NodalPlane(*np[0]) nodal_planes.nodal_plane_2 = NodalPlane(*np[1]) nodal_planes.preferred_plane = 1 if 'Spherical Coordinates' in l: mt = p._mt_sphere(n) moment_tensor.tensor = Tensor( m_rr = mt['Mrr'], m_tt = mt['Mtt'], m_pp = mt['Mff'], m_rt = mt['Mrt'], m_rp = mt['Mrf'], m_tp = mt['Mtf'], ) if 'Eigenvalues and eigenvectors of the Major Double Couple' in l: ax = p._vectors(n) principal_ax.t_axis = Axis(ax['T']['trend'], ax['T']['plunge'], ax['T']['ev']) principal_ax.p_axis = Axis(ax['P']['trend'], ax['P']['plunge'], ax['P']['ev']) principal_ax.n_axis = Axis(ax['N']['trend'], ax['N']['plunge'], ax['N']['ev']) if 'Number of Stations' in l: data_used.station_count = p._number_of_stations(n) if 'Maximum' in l and 'Gap' in l: focal_mech.azimuthal_gap = p._gap(n) if re.match(r'^Date', l): creation_info.creation_time = p._creation_time(n) # Creation Time creation_info.version = orid # Fill in magnitude values magnitude.evaluation_mode = ev_mode magnitude.evaluation_status = ev_stat magnitude.creation_info = creation_info.copy() magnitude.resource_id = self._rid(magnitude) # Stub origin origin.time = ev.get('time') origin.latitude = ev.get('lat') origin.longitude = ev.get('lon') origin.depth = derived_depth * 1000. origin.depth_type = "from moment tensor inversion" origin.creation_info = creation_info.copy() # Unique from true origin ID _oid = self._rid(origin) origin.resource_id = ResourceIdentifier(str(_oid) + '/mt') del _oid # Make an id for the MT that references this origin ogid = str(origin.resource_id) doid = ResourceIdentifier(ogid, referred_object=origin) # Make an id for the moment tensor mag which references this mag mrid = str(magnitude.resource_id) mmid = ResourceIdentifier(mrid, referred_object=magnitude) # MT todo: could check/use URL for RID if parsing the php file moment_tensor.evaluation_mode = ev_mode moment_tensor.evaluation_status = ev_stat moment_tensor.data_used = data_used moment_tensor.moment_magnitude_id = mmid moment_tensor.derived_origin_id = doid moment_tensor.creation_info = creation_info.copy() moment_tensor.resource_id = self._rid(moment_tensor) # Fill in focal_mech values focal_mech.nodal_planes = nodal_planes focal_mech.moment_tensor = moment_tensor focal_mech.principal_axes = principal_ax focal_mech.creation_info = creation_info.copy() focal_mech.resource_id = self._rid(focal_mech) # add mech and new magnitude to event event.focal_mechanisms = [focal_mech] event.magnitudes = [magnitude] event.origins = [origin] event.creation_info = creation_info.copy() # If an MT was done, that's the preferred mag/mech event.preferred_magnitude_id = str(magnitude.resource_id) event.preferred_focal_mechanism_id = str(focal_mech.resource_id) if evid: event.creation_info.version = evid event.resource_id = self._rid(event) self.event = event