def main(): mt = [7.982, -0.154, -7.574, 0.548, 7.147, -0.211] #focal mechanism #mt = [0.,0.,0, 0., 0., 0.] #focal mechanism mopad_mt = MomentTensor(mt, system='NED') bb = BeachBall(mopad_mt, npoints=200) bb._setup_BB(unit_circle=False) # extract the coordinates of the nodal lines neg_nodalline = bb._nodalline_negative pos_nodalline = bb._nodalline_positive #plot radiation pattern and nodal lines pointsp, dispp = farfieldP(mt) pointss, disps = farfieldS(mt) npointsp = pointsp.shape[1] normp = np.sum(pointsp * dispp, axis=0) norms = np.sum(pointss * disps, axis=0) rangep = np.max(np.abs(normp)) ranges = np.max(np.abs(normp)) fig1 = mlab.figure(size=(800, 800), bgcolor=(0, 0, 0)) pts1 = mlab.quiver3d(pointsp[0], pointsp[1], pointsp[2], dispp[0], dispp[1], dispp[2], scalars=normp, vmin=-rangep, vmax=rangep) pts1.glyph.color_mode = 'color_by_scalar' mlab.plot3d(*neg_nodalline, color=(0, 0.5, 0), tube_radius=0.01) mlab.plot3d(*pos_nodalline, color=(0, 0.5, 0), tube_radius=0.01) plot_sphere(0.7) fig2 = mlab.figure(size=(800, 800), bgcolor=(0, 0, 0)) mlab.quiver3d(pointss[0], pointss[1], pointss[2], disps[0], disps[1], disps[2], vmin=-ranges, vmax=ranges) mlab.plot3d(*neg_nodalline, color=(0, 0.5, 0), tube_radius=0.01) mlab.plot3d(*pos_nodalline, color=(0, 0.5, 0), tube_radius=0.01) plot_sphere(0.7) mlab.show()
class SeismicSource(object): """ Set an instance of class SeismicSource() that can be used for earthquake modeling. ______________________________________________________________________ :type mt : list :param mt : Definition of the focal mechanism supported obspy.imaging.scripts.mopad.MomentTensor(). :type poisson: variable :param poisson: Poisson coefficient (0.25 by default). .. example:: ex = NnK.source.SeismicSource([1,2,3,4,5,6]) ex.Aki_Richards.plot('P') .. note:: This object is composed of three classes : MomentTensor, Aki_Richards and Vavryeuk. .. seealso:: :class: `obspy.imaging.scripts.mopad.MomentTensor` :class: `Aki_Richards` :class: `Vavryeuk` ______________________________________________________________________ """ # General attribut definition notes = 'Ceci est à moi' def __init__(self, mt, poisson=0.25): self.MomentTensor = MomentTensor(mt) self.Aki_Richards = Aki_Richards(np.asarray(self.MomentTensor.get_M('XYZ'))) self.Vavryeuk = Vavryeuk(np.asarray(self.MomentTensor.get_M('XYZ')),poisson = poisson)
def test(): sdr = [175, 75, -30] plot_farfield(sdr, points=nice_points(), plot_pt=True) plot_farfield(sdr, typ='S', points=nice_points(), plot_pt=True) mt = strikediprake_2_moments(*sdr) # NED obj = MomentTensor(mt) obj._M_to_principal_axis_system() print(obj.get_fps()) print(obj.get_p_axis(style='f')) print(obj.get_t_axis(style='f')) print(obj.get_null_axis(style='f')) print(pnt_axis(mt, out='xyz')) print(pnt_axis(mt, out='rad')) plt.show() #test()
def _write_radiation_pattern_vtk(ned_mt, fname_rpattern='rpattern.vtk', fname_beachlines='beachlines.vtk'): # output a vtkfile that can for exampled be displayed by ParaView mtensor = MomentTensor(ned_mt, system='NED') bb = BeachBall(mtensor, npoints=200) bb._setup_BB(unit_circle=False) # extract the coordinates of the nodal lines neg_nodalline = bb._nodalline_negative pos_nodalline = bb._nodalline_positive # plot radiation pattern and nodal lines points = _equalarea_spherical_grid() ndim, npoints = points.shape dispp = farfield(ned_mt, points, type="P") disps = farfield(ned_mt, points, type="S") # write vector field with open(fname_rpattern, 'w') as vtk_file: vtk_header = '# vtk DataFile Version 2.0\n' + \ 'radiation pattern vector field\n' + \ 'ASCII\n' + \ 'DATASET UNSTRUCTURED_GRID\n' + \ 'POINTS {:d} float\n'.format(npoints) vtk_file.write(vtk_header) # write point locations for x, y, z in np.transpose(points): vtk_file.write('{:.3e} {:.3e} {:.3e}\n'.format(x, y, z)) # write vector field vtk_file.write('POINT_DATA {:d}\n'.format(npoints)) vtk_file.write('VECTORS s_radiation float\n') for x, y, z in np.transpose(disps): vtk_file.write('{:.3e} {:.3e} {:.3e}\n'.format(x, y, z)) vtk_file.write('VECTORS p_radiation float\n'.format(npoints)) for x, y, z in np.transpose(dispp): vtk_file.write('{:.3e} {:.3e} {:.3e}\n'.format(x, y, z)) # write nodal lines with open(fname_beachlines, 'w') as vtk_file: npts_neg = neg_nodalline.shape[1] npts_pos = pos_nodalline.shape[1] npts_tot = npts_neg + npts_pos vtk_header = '# vtk DataFile Version 2.0\n' + \ 'beachball nodal lines\n' + \ 'ASCII\n' + \ 'DATASET UNSTRUCTURED_GRID\n' + \ 'POINTS {:d} float\n'.format(npts_tot) vtk_file.write(vtk_header) # write point locations for x, y, z in np.transpose(neg_nodalline): vtk_file.write('{:.3e} {:.3e} {:.3e}\n'.format(x, y, z)) for x, y, z in np.transpose(pos_nodalline): vtk_file.write('{:.3e} {:.3e} {:.3e}\n'.format(x, y, z)) # write line segments vtk_file.write('\nCELLS 2 {:d}\n'.format(npts_tot + 4)) ipoints = list(range(0, npts_neg)) + [0] vtk_file.write('{:d} '.format(npts_neg + 1)) for ipoint in ipoints: if ipoint % 30 == 29: vtk_file.write('\n') vtk_file.write('{:d} '.format(ipoint)) vtk_file.write('\n') ipoints = list(range(0, npts_pos)) + [0] vtk_file.write('{:d} '.format(npts_pos + 1)) for ipoint in ipoints: if ipoint % 30 == 29: vtk_file.write('\n') vtk_file.write('{:d} '.format(ipoint + npts_neg)) vtk_file.write('\n') # cell types. 4 means cell type is a poly_line vtk_file.write('\nCELL_TYPES 2\n') vtk_file.write('4\n4')
def _plot_radiation_pattern_mayavi(ned_mt): """ Plot the radiation pattern using MayaVi. This private function uses the mayavi (vtk) library to plot the radiation pattern to screen. Note that you might have to set the QT_API environmental variable to e.g. export QT_API=pyqt that mayavi works properly. :param ned_mt: moment tensor in NED convention """ # use mayavi if possible. try: from mayavi import mlab except Exception as err: print(err) msg = ("ObsPy failed to import MayaVi. " "You need to install the mayavi module " "(e.g. 'conda install mayavi', 'pip install mayavi'). " "If it is installed and still doesn't work, " "try setting the environmental variable QT_API to " "pyqt (e.g. export QT_API=pyqt) before running the " "code. Another option is to avoid mayavi and " "directly use kind='vtk' for vtk file output of the " "radiation pattern that can be used by external " "software like ParaView") raise ImportError(msg) # get mopad moment tensor mopad_mt = MomentTensor(ned_mt, system='NED') bb = BeachBall(mopad_mt, npoints=200) bb._setup_BB(unit_circle=False) # extract the coordinates of the nodal lines neg_nodalline = bb._nodalline_negative pos_nodalline = bb._nodalline_positive # add the first point to the end to close the nodal line neg_nodalline = np.hstack((neg_nodalline, neg_nodalline[:, 0][:, None])) pos_nodalline = np.hstack((pos_nodalline, pos_nodalline[:, 0][:, None])) # plot radiation pattern and nodal lines points = _equalarea_spherical_grid(nlat=20) dispp = farfield(ned_mt, points, type="P") disps = farfield(ned_mt, points, type="S") # get vector lengths normp = np.sum(dispp * points, axis=0) normp /= np.max(np.abs(normp)) norms = np.sqrt(np.sum(disps * disps, axis=0)) norms /= np.max(np.abs(norms)) # make sphere to block view to the other side of the beachball rad = 0.8 pi = np.pi cos = np.cos sin = np.sin phi, theta = np.mgrid[0:pi:101j, 0:2 * pi:101j] x = rad * sin(phi) * cos(theta) y = rad * sin(phi) * sin(theta) z = rad * cos(phi) # p wave radiation pattern mlab.figure(size=(800, 800), bgcolor=(0, 0, 0)) pts1 = mlab.quiver3d(points[0], points[1], points[2], dispp[0], dispp[1], dispp[2], scalars=normp, vmin=-1., vmax=1.) pts1.glyph.color_mode = 'color_by_scalar' mlab.plot3d(*neg_nodalline, color=(0, 0.5, 0), tube_radius=0.01) mlab.plot3d(*pos_nodalline, color=(0, 0.5, 0), tube_radius=0.01) mlab.mesh(x, y, z, color=(0, 0, 0)) # s wave radiation pattern mlab.figure(size=(800, 800), bgcolor=(0, 0, 0)) pts2 = mlab.quiver3d(points[0], points[1], points[2], disps[0], disps[1], disps[2], scalars=norms, vmin=-0., vmax=1.) pts2.glyph.color_mode = 'color_by_scalar' mlab.plot3d(*neg_nodalline, color=(0, 0.5, 0), tube_radius=0.01) mlab.plot3d(*pos_nodalline, color=(0, 0.5, 0), tube_radius=0.01) mlab.mesh(x, y, z, color=(0, 0, 0)) mlab.show()
def _plot_radiation_pattern_sphere(ax3d, ned_mt, type, p_sphere_direction='inwards'): """ Private function that plots a radiation pattern sphere into an :class:`~mpl_toolkits.mplot3d.axes3d.Axes3D`. :type ax3d: :class:`mpl_toolkits.mplot3d.axes3d.Axes3D` :param ax3d: matplotlib Axes3D object :param ned_mt: moment tensor in NED convention :param p_sphere_direction: If this is 'inwards', the tension regions of the beachball deform the radiation sphere inwards. If 'outwards' it deforms outwards. :param type: 'P' or 'S' (P or S wave). """ import matplotlib.pyplot as plt type = type.upper() if type not in ("P", "S"): msg = ("type must be 'P' or 'S'") raise ValueError(msg) is_p_wave = type == "P" # generate spherical mesh that is aligned with the moment tensor null # axis. MOPAD should use NED coordinate system to avoid internal # coordinate transformations mtensor = MomentTensor(ned_mt, system='NED') # use the most isolated eigenvector as axis of symmetry evecs = mtensor.get_eigvecs() evals = np.abs(mtensor.get_eigvals())**2 evals_dev = np.abs(evals - np.mean(evals)) if is_p_wave: if p_sphere_direction == 'outwards': evec_max = evecs[np.argmax(evals_dev)] elif p_sphere_direction == 'inwards': evec_max = evecs[np.argmax(evals)] else: evec_max = evecs[np.argmax(evals_dev)] orientation = np.ravel(evec_max) # get a uv sphere that is oriented along the moment tensor axes ntheta, nphi = 100, 100 points = _oriented_uv_sphere(ntheta=ntheta, nphi=nphi, orientation=orientation) sshape = (ntheta, nphi) # get radiation pattern if is_p_wave: disp = farfield(ned_mt, points, type="P") magn = np.sum(disp * points, axis=0) cmap = get_cmap('bwr') norm = plt.Normalize(-1, 1) else: disp = farfield(ned_mt, points, type="S") magn = np.sqrt(np.sum(disp * disp, axis=0)) cmap = get_cmap('Greens') norm = plt.Normalize(0, 1) magn /= np.max(np.abs(magn)) # compute colours and displace points along normal if is_p_wave: if p_sphere_direction == 'outwards': points *= (1. + np.abs(magn) / 2.) elif p_sphere_direction == 'inwards': points *= (1. + magn / 2.) else: points *= (1. + magn / 2.) colors = np.array([cmap(norm(val)) for val in magn]) colors = colors.reshape(ntheta, nphi, 4) x = points[0].reshape(sshape) y = points[1].reshape(sshape) z = points[2].reshape(sshape) # plot 3d radiation pattern ax3d.plot_surface(x, y, z, rstride=4, cstride=4, facecolors=colors) ax3d.set(xlim=(-1.5, 1.5), ylim=(-1.5, 1.5), zlim=(-1.5, 1.5), xticks=[-1, 1], yticks=[-1, 1], zticks=[-1, 1], xticklabels=['South', 'North'], yticklabels=['West', 'East'], zticklabels=['Up', 'Down'], title='{} wave farfield'.format(type)) ax3d.view_init(elev=-110., azim=0.)
def _plot_radiation_pattern_sphere( ax3d, ned_mt, type, p_sphere_direction='inwards'): """ Private function that plots a radiation pattern sphere into an :class:`~mpl_toolkits.mplot3d.axes3d.Axes3D`. :type ax3d: :class:`mpl_toolkits.mplot3d.axes3d.Axes3D` :param ax3d: matplotlib Axes3D object :param ned_mt: moment tensor in NED convention :param p_sphere_direction: If this is 'inwards', the tension regions of the beachball deform the radiation sphere inwards. If 'outwards' it deforms outwards. :param type: 'P' or 'S' (P or S wave). """ import matplotlib.pyplot as plt type = type.upper() if type not in ("P", "S"): msg = ("type must be 'P' or 'S'") raise ValueError(msg) is_p_wave = type == "P" # generate spherical mesh that is aligned with the moment tensor null # axis. MOPAD should use NED coordinate system to avoid internal # coordinate transformations mtensor = MomentTensor(ned_mt, system='NED') # use the most isolated eigenvector as axis of symmetry evecs = mtensor.get_eigvecs() evals = np.abs(mtensor.get_eigvals())**2 evals_dev = np.abs(evals - np.mean(evals)) if is_p_wave: if p_sphere_direction == 'outwards': evec_max = evecs[np.argmax(evals_dev)] elif p_sphere_direction == 'inwards': evec_max = evecs[np.argmax(evals)] else: evec_max = evecs[np.argmax(evals_dev)] orientation = np.ravel(evec_max) # get a uv sphere that is oriented along the moment tensor axes ntheta, nphi = 100, 100 points = _oriented_uv_sphere(ntheta=ntheta, nphi=nphi, orientation=orientation) sshape = (ntheta, nphi) # get radiation pattern if is_p_wave: disp = farfield(ned_mt, points, type="P") magn = np.sum(disp * points, axis=0) cmap = get_cmap('bwr') norm = plt.Normalize(-1, 1) else: disp = farfield(ned_mt, points, type="S") magn = np.sqrt(np.sum(disp * disp, axis=0)) cmap = get_cmap('Greens') norm = plt.Normalize(0, 1) magn /= np.max(np.abs(magn)) # compute colours and displace points along normal if is_p_wave: if p_sphere_direction == 'outwards': points *= (1. + np.abs(magn) / 2.) elif p_sphere_direction == 'inwards': points *= (1. + magn / 2.) else: points *= (1. + magn / 2.) colors = np.array([cmap(norm(val)) for val in magn]) colors = colors.reshape(ntheta, nphi, 4) x = points[0].reshape(sshape) y = points[1].reshape(sshape) z = points[2].reshape(sshape) # plot 3d radiation pattern ax3d.plot_surface(x, y, z, rstride=4, cstride=4, facecolors=colors) ax3d.set(xlim=(-1.5, 1.5), ylim=(-1.5, 1.5), zlim=(-1.5, 1.5), xticks=[-1, 1], yticks=[-1, 1], zticks=[-1, 1], xticklabels=['South', 'North'], yticklabels=['West', 'East'], zticklabels=['Up', 'Down'], title='{} wave farfield'.format(type)) ax3d.view_init(elev=-110., azim=0.)
def __init__(self, mt, poisson=0.25): self.MomentTensor = MomentTensor(mt) self.Aki_Richards = Aki_Richards(np.asarray(self.MomentTensor.get_M('XYZ'))) self.Vavryeuk = Vavryeuk(np.asarray(self.MomentTensor.get_M('XYZ')),poisson = poisson)
def mt_angles(mt): """ Takes 6 components and returns fps tri-angles in degrees, with deviatoric, isotropic, DC and CLVD percentages. ______________________________________________________________________ :type mt : list or np.array. :param mt : moment tensor NM x 6 (Mxx, Myy, Mzz, Mxy, Mxz, Myz, the six independent components). :rtype : np.array [[1x3], [1x4]]. :return : full 3x3 moment tensor. .. note:: Nan value are returned for unknown parameters. The deviatoric percentage is the sum of DC and CLVD percentages. Use obspy.imaging.scripts.mopad to get correct input. ______________________________________________________________________ """ # Make sure we got np.array if np.asarray(mt) is not mt: mt = np.asarray(mt) # Getting various formats ## if given strike, dip, rake if mt.shape == (3,): strike, dip, rake = mt DC = 100 CLVD = 0 iso = 0 devi = 100 ## if given [[strike, dip, rake], [strike, dip, rake]] (e.g. by MoPad) elif mt.shape == (2,3) : strike, dip, rake = mt[0] DC = 100 CLVD = 0 iso = 0 devi = 100 ## if given [strike, dip, rake, devi] elif mt.shape == (4,): strike, dip, rake, devi = mt DC = np.nan CLVD = np.nan iso = 0 ## if given [Mxx, Myy, Mzz, Mxy, Mxz, Myz] elif mt.shape == (6,) : mt = MomentTensor(mt,'XYZ') DC = mt.get_DC_percentage() CLVD = mt.get_CLVD_percentage() iso = mt.get_iso_percentage() devi = mt.get_devi_percentage() mt = mt_angles(mt.get_fps()) strike, dip, rake = mt[0] ## if given full moment tensor elif mt.shape == (3,3) : mt = mt_angles([mt[0,0], mt[1,1], mt[2,2], mt[0,1], mt[0,2], mt[1,2]]) strike, dip, rake = mt[0] DC, CLVD, iso, devi = mt[1] else: raise Exception('I/O dimensions: only [1|2]x3, 1x[4|6] and 3x3 inputs supported.') return np.array([[strike, dip, rake], [DC, CLVD, iso, devi]])