def fill_tensor_from_components(mrr, mtt, mpp, mrt, mrp, mtp, source='unknown', mtype='unknown'): """Fill in moment tensor parameters from moment tensor components. Args: strike (float): Strike from (assumed) first nodal plane (degrees). dip (float): Dip from (assumed) first nodal plane (degrees). rake (float): Rake from (assumed) first nodal plane (degrees). magnitude (float): Magnitude for moment tensor (not required if using moment tensor for angular comparisons.) Returns: dict: Fully descriptive moment tensor dictionary, including fields: - mrr,mtt,mpp,mrt,mrp,mtp Moment tensor components. - T T-axis values: - azimuth (degrees) - plunge (degrees) - N N-axis values: - azimuth (degrees) - plunge (degrees) - P P-axis values: - azimuth (degrees) - plunge (degrees) - NP1 First nodal plane values: - strike (degrees) - dip (degrees) - rake (degrees) - NP2 Second nodal plane values: - strike (degrees) - dip (degrees) - rake (degrees) """ tensor_params = { 'mrr': mrr, 'mtt': mtt, 'mpp': mpp, 'mrt': mrt, 'mrp': mrp, 'mtp': mtp } tensor_params['source'] = source tensor_params['type'] = mtype mt = MomentTensor(mrr, mtt, mpp, mrt, mrp, mtp, 1) tnp1 = mt2plane(mt) np1 = {'strike': tnp1.strike, 'dip': tnp1.dip, 'rake': tnp1.rake} tensor_params['NP1'] = np1.copy() strike2, dip2, rake2 = aux_plane(np1['strike'], np1['dip'], np1['rake']) np2 = {'strike': strike2, 'dip': dip2, 'rake': rake2} tensor_params['NP2'] = np2.copy() T, N, P = mt2axes(mt) tensor_params['T'] = {'azimuth': T.strike, 'value': T.val, 'plunge': T.dip} tensor_params['N'] = {'azimuth': N.strike, 'value': N.val, 'plunge': N.dip} tensor_params['P'] = {'azimuth': P.strike, 'value': P.val, 'plunge': P.dip} return tensor_params
def test_MT2Plane(self): """ Tests mt2plane. """ mt = MomentTensor((0.91, -0.89, -0.02, 1.78, -1.55, 0.47), 0) np = mt2plane(mt) self.assertAlmostEqual(np.strike, 129.86262672080011) self.assertAlmostEqual(np.dip, 79.022700906654734) self.assertAlmostEqual(np.rake, 97.769255185515192)
def test_mt2plane(self): """ Tests mt2plane. """ mt = MomentTensor((0.91, -0.89, -0.02, 1.78, -1.55, 0.47), 0) np = mt2plane(mt) assert round(abs(np.strike - 129.86262672080011), 7) == 0 assert round(abs(np.dip - 79.022700906654734), 7) == 0 assert round(abs(np.rake - 97.769255185515192), 7) == 0
def convert_to_antelope(M, cenloc): """ Convert Roberto's wphase output to antelope's moment tensor format. Plus calculate a few values based on the moment tensor. :param M: Moment tensor :param cenloc: The centroid location, (cenlat,cenlon,cendep) :return: antelope's moment tensor info in a dictionary. """ M2 = np.asarray(M)**2 m0 = np.sqrt(0.5*(M2[0]+M2[1]+M2[2])+M2[3]+M2[4]+M2[5]) mag = 2./3.*(np.log10(m0)-9.10) np1 = mt2plane(MomentTensor(M, 0)) np2 = aux_plane(np1.strike, np1.dip, np1.rake) results = model.AntelopeMomentTensor( tmpp=M[2], tmrp=M[4], tmrr=M[0], tmrt=M[3], tmtp=M[5], tmtt=M[1], scm=m0, drmag=mag, drmagt='Mww', drlat=cenloc[0], drlon=cenloc[1], drdepth=cenloc[2], str1=np1.strike, dip1=np1.dip, rake1=np1.rake, str2=np2[0], dip2=np2[1], rake2=np2[2], auth=settings.AUTHORITY, ) try: results.dc, results.clvd = decomposeMT(M) except Exception: import traceback logger.warning("Error computing DC/CLVD decomposition: %s", traceback.format_exc()) return results
def mt2parameters(MTx, M, gfscale): #Iso Mo MoIso = (MTx[0][0] + MTx[1][1] + MTx[2][2]) / 3 c = MomentTensor(MTx[2][2], MTx[0][0], MTx[1][1], MTx[0][2], -MTx[1][2], -MTx[0][1], gfscale) # Principal axes (T, N, P) = MT2Axes(c) # Nodal planes np0 = MT2Plane(c) np2 = AuxPlane(np0.strike, np0.dip, np0.rake) # Convention rake: up-down if (np0.rake > 180): np0.rake = np0.rake - 360 if (np0.rake < -180): np0.rake = np0.rake + 360 np1 = np.zeros(3.) np1 = [np0.strike, np0.dip, np0.rake] # Compute Eigenvectors and Eigenvalues # Seismic Moment and Moment Magnitude (EigVal, EigVec) = np.linalg.eig(MTx) b = copy.deepcopy(EigVal) b.sort() Mo = (abs(b[0]) + abs(b[2])) / 2. Mw = math.log10(Mo) / 1.5 - 10.73 # Compute double-couple, CLVD & iso d = copy.deepcopy(EigVal) d[0] = abs(d[0]) d[1] = abs(d[1]) d[2] = abs(d[2]) d.sort() eps = abs(d[0]) / abs(d[2]) pcdc = 100.0 * (1.0 - 2.0 * eps) pcclvd = 200.0 * eps pcdc = pcdc / 100.0 pcclvd = pcclvd / 100.0 pciso = abs(MoIso) / Mo pcsum = pcdc + pcclvd + pciso pcdc = 100.0 * pcdc / pcsum pcclvd = 100.0 * pcclvd / pcsum pciso = 100.0 * pciso / pcsum Pdc = pcdc Pclvd = pcclvd return (Mo, Mw, Pdc, Pclvd, EigVal, EigVec, T, N, P, np1, np2)
def test_MT2Axes(self): """ Tests mt2axes. """ # http://en.wikipedia.org/wiki/File:USGS_sumatra_mts.gif mt = MomentTensor((0.91, -0.89, -0.02, 1.78, -1.55, 0.47), 0) (T, N, P) = mt2axes(mt) self.assertAlmostEqual(T.val, 2.52461359) self.assertAlmostEqual(T.dip, 55.33018576) self.assertAlmostEqual(T.strike, 49.53656116) self.assertAlmostEqual(N.val, 0.08745048) self.assertAlmostEqual(N.dip, 7.62624529) self.assertAlmostEqual(N.strike, 308.37440488) self.assertAlmostEqual(P.val, -2.61206406) self.assertAlmostEqual(P.dip, 33.5833323) self.assertAlmostEqual(P.strike, 213.273886)
def test_mt2axes(self): """ Tests mt2axes. """ # https://en.wikipedia.org/wiki/File:USGS_sumatra_mts.gif mt = MomentTensor((0.91, -0.89, -0.02, 1.78, -1.55, 0.47), 0) (t, n, p) = mt2axes(mt) assert round(abs(t.val - 2.52461359), 7) == 0 assert round(abs(t.dip - 55.33018576), 7) == 0 assert round(abs(t.strike - 49.53656116), 7) == 0 assert round(abs(n.val - 0.08745048), 7) == 0 assert round(abs(n.dip - 7.62624529), 7) == 0 assert round(abs(n.strike - 308.37440488), 7) == 0 assert round(abs(p.val - -2.61206406), 7) == 0 assert round(abs(p.dip - 33.5833323), 7) == 0 assert round(abs(p.strike - 213.273886), 7) == 0
def decomposeMT(M): """Given a deviatoric (i.e. trace-free) moment tensor (specified as a 6-element list in the CMT convention as usual), compute the percentage double-couple and compensated linear vector dipole components. Written following this paper: Vavryčuk, V. Moment tensor decompositions revisited. J Seismol 19, 231–252 (2015). https://doi.org/10.1007/s10950-014-9463-y :returns: A tuple ``(DC, CLVD)`` of relative scale factors between 0 and 1. """ mt = MomentTensor(M, 0) eigs, _ = np.linalg.eig(mt.mt) M1, M2, M3 = np.sort(eigs)[::-1] # M1 >= M2 >= M3 # Since we're working with deviatoric moment tensors, we are assuming # M_ISO=0 and we don't have to worry about the destinction between the # Silver&Jordan and Knopoff&Randall decompositions. M_CLVD = (2./3.)*(M1 + M3 - 2*M2) M_DC = (1./2.)*(M1 - M3 - abs(M1 + M3 - 2*M2)) M = abs(M_CLVD) + abs(M_DC) return abs(M_DC)/M, abs(M_CLVD)/M
def main(): parser = argparse.ArgumentParser( description='Ternary plot to display the type pf mechanism') group_input = parser.add_mutually_exclusive_group(required=False) group_input.add_argument( '-c', '--cmtfile', help='Give a file at the CMTSOLUTION format from the Global CMT catalog' ) group_input.add_argument( '--mt', help= 'Give the moment tensor in the following order: Mrr,Mtt,Mpp,Mrt,Mrp,Mtp', nargs=6, type=float, metavar=("Mrr", "Mtt", "Mpp", "Mrt", "Mrp", "Mtp")) group_input.add_argument('--np', help='Give nodal plane angle (strike,dip,slip)', nargs=3, type=float, metavar=("strike", "dip", "slip")) parser.add_argument('--infile', help='read input file with several moment tensor') parser.add_argument('--debug', help='debug mode', action='store_true') parser.add_argument('-o', '--output', help='save figure (png, svg, eps, pdf)') args = parser.parse_args() if args.infile: fm = read_foc_mec_file(args.infile) print fm if args.cmtfile: cmtfile = args.cmtfile cmt_dict = parse_cmt(cmtfile) Mrr = float(cmt_dict['Mrr']) Mtt = float(cmt_dict['Mtt']) Mpp = float(cmt_dict['Mpp']) Mrt = float(cmt_dict['Mrt']) Mrp = float(cmt_dict['Mrp']) Mtp = float(cmt_dict['Mtp']) elif args.mt: Mrr = args.mt[0] Mtt = args.mt[1] Mpp = args.mt[2] Mrt = args.mt[3] Mrp = args.mt[4] Mtp = args.mt[5] elif args.np: Mrr, Mtt, Mpp, Mrt, Mrp, Mtp = sdrToMt(args.np[0], args.np[1], args.np[2]) M = MomentTensor((Mrr, Mtt, Mpp, Mrt, Mrp, Mtp), 0) # principal axes (T, N, P) = mt2axes(M) if args.debug: print "Moment tensor: \n Mrr :",Mrr, \ "\n Mtt :",Mtt, \ "\n Mpp :",Mpp, \ "\n Mrt :",Mrt, \ "\n Mrp :",Mrp, \ "\n Mtp :",Mtp print "PRINCIPAL AXES:" print "T axis: VAL = ", round(T.val), " PLG = ", round( T.dip), "AZM = ", round(T.strike) print "N axis: VAL = ", round(N.val), " PLG = ", round( N.dip), "AZM = ", round(N.strike) print "P axis: VAL = ", round(P.val), " PLG = ", round( P.dip), "AZM = ", round(P.strike) x = sin(T.dip * degtorad) y = sin(N.dip * degtorad) z = sin(P.dip * degtorad) data = np.array([[y, z, x]]) tri = ternaryDiagram() tri.background() tri.plot_data(data, M) if args.output: plt.savefig(output, bbox_inches='tight') else: plt.show()
is2 = 1 / sqrt(2.0) mrr = is2 * (sin(2 * dip) * sin(rake)) mtt = -is2 * (sin(dip) * cos(rake) * sin(2 * strike) + sin(2 * dip) * sin(rake) * sin(strike)**2) mpp = is2 * (sin(dip) * cos(rake) * sin(2 * strike) - sin(2 * dip) * sin(rake) * cos(strike)**2) mtp = -is2 * (sin(dip) * cos(rake) * cos(2 * strike) + 0.5 * sin(2 * dip) * sin(rake) * sin(2 * strike)) mrp = is2 * (cos(dip) * cos(rake) * sin(strike) - cos(2 * dip) * sin(rake) * cos(strike)) mrt = -is2 * (cos(dip) * cos(rake) * cos(strike) + cos(2 * dip) * sin(rake) * sin(strike)) mt = MomentTensor((mrr, mtt, mpp, mrt, mrp, mtp), 0) # principal axes (T, N, P) = mt2axes(mt) # output print " " print "MOMENT TENSOR:" print "MRR = ", mrr print "MTT = ", mtt print "MPP = ", mpp print "MTP = ", mtp print "MRP = ", mrp print "MRT = ", mrt
def main(): parser = argparse.ArgumentParser( description= 'Draws a beachball of an earthquake focal mechanism given strike, dip, rake or the 6 components of the moment tensor' ) parser.add_argument( '--fm', help= 'Nodal plane (strike dip rake) or moment tensor (Mrr Mtt Mpp Mrt Mrp Mtp)', type=float, nargs='+') parser.add_argument('--dc', help='superpose the double couple component', action='store_true') parser.add_argument( '-c', '--color', help= 'Choose a color for the quadrant of tension (r,b,k,g,y...). Default color is red', default='r', type=str) parser.add_argument( '-o', '--output', help= 'Name of the output file (could be a png, ps, pdf,eps, and svg). Default is None', default=None, type=str) args = parser.parse_args() bb = BB(outputname=args.output, facecolor=args.color) NP = None if args.fm: if len(args.fm) == 6: print "Draw beachball from moment tensor" Mrr = args.fm[0] Mtt = args.fm[1] Mpp = args.fm[2] Mrt = args.fm[3] Mrp = args.fm[4] Mtp = args.fm[5] M = MomentTensor((Mrr, Mtt, Mpp, Mrt, Mrp, Mtp), 0) nod_planes = mt2plane(M) if args.dc: NP = (nod_planes.strike, nod_planes.dip, nod_planes.rake) s2, d2, r2 = aux_plane(nod_planes.strike, nod_planes.dip, nod_planes.rake) print "Moment tensor:", \ "\n Mrr :",Mrr, \ "\n Mtt :",Mtt, \ "\n Mpp :",Mpp, \ "\n Mrt :",Mrt, \ "\n Mrp :",Mrp, \ "\n Mtp :",Mtp print "NP1:", round(nod_planes.strike), round( nod_planes.dip), round(nod_planes.rake) print "NP2:", round(s2), round(d2), round(r2) elif len(args.fm) == 3: print "Draw beachball from nodal plane" # compute auxiliary plane s2, d2, r2 = aux_plane(args.fm[0], args.fm[1], args.fm[2]) print "NP1:", round(args.fm[0]), round(args.fm[1]), round( args.fm[2]) print "NP2:", round(s2), round(d2), round(r2) bb.draw(args.fm, NP=NP)