def _parseRecordDa(self, line, focal_mechanism): """ Parses the 'source parameter data - principal axes and nodal planes' record Da """ exponent = self._intZero(line[3:5]) scale = math.pow(10, exponent) t_axis_len = self._floatWithFormat(line[5:9], '4.2', scale) t_axis_stderr = self._floatWithFormat(line[9:12], '3.2', scale) t_axis_plunge = self._int(line[12:14]) t_axis_azimuth = self._int(line[14:17]) n_axis_len = self._floatWithFormat(line[17:21], '4.2', scale) n_axis_stderr = self._floatWithFormat(line[21:24], '3.2', scale) n_axis_plunge = self._int(line[24:26]) n_axis_azimuth = self._int(line[26:29]) p_axis_len = self._floatWithFormat(line[29:33], '4.2', scale) p_axis_stderr = self._floatWithFormat(line[33:36], '3.2', scale) p_axis_plunge = self._int(line[36:38]) p_axis_azimuth = self._int(line[38:41]) np1_strike = self._int(line[42:45]) np1_dip = self._int(line[45:47]) np1_slip = self._int(line[47:51]) np2_strike = self._int(line[51:54]) np2_dip = self._int(line[54:56]) np2_slip = self._int(line[56:60]) t_axis = Axis() t_axis.length = t_axis_len self._storeUncertainty(t_axis.length_errors, t_axis_stderr) t_axis.plunge = t_axis_plunge t_axis.azimuth = t_axis_azimuth n_axis = Axis() n_axis.length = n_axis_len self._storeUncertainty(n_axis.length_errors, n_axis_stderr) n_axis.plunge = n_axis_plunge n_axis.azimuth = n_axis_azimuth p_axis = Axis() p_axis.length = p_axis_len self._storeUncertainty(p_axis.length_errors, p_axis_stderr) p_axis.plunge = p_axis_plunge p_axis.azimuth = p_axis_azimuth principal_axes = PrincipalAxes() principal_axes.t_axis = t_axis principal_axes.n_axis = n_axis principal_axes.p_axis = p_axis focal_mechanism.principal_axes = principal_axes nodal_plane_1 = NodalPlane() nodal_plane_1.strike = np1_strike nodal_plane_1.dip = np1_dip nodal_plane_1.rake = np1_slip nodal_plane_2 = NodalPlane() nodal_plane_2.strike = np2_strike nodal_plane_2.dip = np2_dip nodal_plane_2.rake = np2_slip nodal_planes = NodalPlanes() nodal_planes.nodal_plane_1 = nodal_plane_1 nodal_planes.nodal_plane_2 = nodal_plane_2 focal_mechanism.nodal_planes = nodal_planes
def _parse_record_da(self, line, focal_mechanism): """ Parses the 'source parameter data - principal axes and nodal planes' record Da """ exponent = self._int_zero(line[3:5]) scale = math.pow(10, exponent) t_axis_len = self._float_with_format(line[5:9], '4.2', scale) t_axis_stderr = self._float_with_format(line[9:12], '3.2', scale) t_axis_plunge = self._int(line[12:14]) t_axis_azimuth = self._int(line[14:17]) n_axis_len = self._float_with_format(line[17:21], '4.2', scale) n_axis_stderr = self._float_with_format(line[21:24], '3.2', scale) n_axis_plunge = self._int(line[24:26]) n_axis_azimuth = self._int(line[26:29]) p_axis_len = self._float_with_format(line[29:33], '4.2', scale) p_axis_stderr = self._float_with_format(line[33:36], '3.2', scale) p_axis_plunge = self._int(line[36:38]) p_axis_azimuth = self._int(line[38:41]) np1_strike = self._int(line[42:45]) np1_dip = self._int(line[45:47]) np1_slip = self._int(line[47:51]) np2_strike = self._int(line[51:54]) np2_dip = self._int(line[54:56]) np2_slip = self._int(line[56:60]) t_axis = Axis() t_axis.length = t_axis_len self._store_uncertainty(t_axis.length_errors, t_axis_stderr) t_axis.plunge = t_axis_plunge t_axis.azimuth = t_axis_azimuth n_axis = Axis() n_axis.length = n_axis_len self._store_uncertainty(n_axis.length_errors, n_axis_stderr) n_axis.plunge = n_axis_plunge n_axis.azimuth = n_axis_azimuth p_axis = Axis() p_axis.length = p_axis_len self._store_uncertainty(p_axis.length_errors, p_axis_stderr) p_axis.plunge = p_axis_plunge p_axis.azimuth = p_axis_azimuth principal_axes = PrincipalAxes() principal_axes.t_axis = t_axis principal_axes.n_axis = n_axis principal_axes.p_axis = p_axis focal_mechanism.principal_axes = principal_axes nodal_plane_1 = NodalPlane() nodal_plane_1.strike = np1_strike nodal_plane_1.dip = np1_dip nodal_plane_1.rake = np1_slip nodal_plane_2 = NodalPlane() nodal_plane_2.strike = np2_strike nodal_plane_2.dip = np2_dip nodal_plane_2.rake = np2_slip nodal_planes = NodalPlanes() nodal_planes.nodal_plane_1 = nodal_plane_1 nodal_planes.nodal_plane_2 = nodal_plane_2 focal_mechanism.nodal_planes = nodal_planes
def _map_fplane2focalmech(self, db): """ Return an obspy FocalMechanism from an dict of CSS key/values corresponding to one record. See the 'Join' section for the implied database join expected. Inputs ====== db : dict of key/values of CSS fields from the 'fplane' table Returns ======= obspy.core.event.FocalMechanism Notes ===== Any object that supports the dict 'get' method can be passed as input, e.g. OrderedDict, custom classes, etc. """ # # NOTE: Antelope schema for this is wrong, no nulls defined # fm = FocalMechanism() nps = NodalPlanes() nps.nodal_plane_1 = NodalPlane(db.get('str1'), db.get('dip1'), db.get('rake1')) nps.nodal_plane_2 = NodalPlane(db.get('str2'), db.get('dip2'), db.get('rake2')) nps.preferred_plane = 1 prin_ax = PrincipalAxes() prin_ax.t_axis = Axis(db.get('taxazm'),db.get('taxplg')) prin_ax.p_axis = Axis(db.get('paxazm'),db.get('paxplg')) fm.nodal_planes = nps fm.principal_axes = prin_ax author_string = ':'.join([db['algorithm'], db['auth']]) fm.creation_info = CreationInfo( version = db.get('mechid'), creation_time = UTCDateTime(db['lddate']), agency_id = self.agency, author = author_string, ) fm.resource_id = self._rid(fm) return fm
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