本文简介Python包 SPECNM使用方法
参考:https://gitlab.com/JohKem1/specnm
安装
使用anaconda安装。
配置conda源
官方:Please also setup the conda-forge channel to allow for installation of all required packages:
1 | conda config --add channels conda-forge |
选择一个空目录,复制specnm包
1 | git clone https://gitlab.com/JohKem1/specnm.git |
选择specnm所在目录
1 | cd specnm |
创建一个anaconda环境,用于安装specnm。可以使用已有的环境,但是不确定其他包是否兼容。
1 | conda env create -f specnm.yml |
此时可能会出现依赖包 percache 不存在的情况,可能是conda源不存在percache,因此可以手动使用pip安装:
1 | pip install percache |
如果有其他包不存在也可以用此方式手动安装。
安装specnm;进行conda develop。
1 | conda develop . |
运行测试
1 | pytest |
若无法通过测试,可以尝试:
git下载的specnm文件夹中还有一个名为specnm的文件夹,cd进入这个文件夹后能够看到love.py等函数文件,先进入这个文件夹再进行conda develop
1 | cd specnm |
计算环型振型相关信息
注意:无法限定radial order(径向阶数),只能使用angular order(角度阶数)和频率范围限定计算的振型边界范围。在计算PREM模型时,由于缺少0T1振型,因此n(radial order)的赋值存在偏差,真正的n值=赋值数+1。下文示例中存在该问题。
2024.5.28 修改了振型n值创建方式,去除了理论上不存在的0T1振型。
1 | from specnm import love |
ray_out为存储相关振型信息的字典,其中:
- angular orders
- wave numbers
- frequencies
- angular frequencies :2pifrequencies
- eigenfunctions :为一个二维列表,每一个列表为对应频率振型的本征函数,即ray_out[‘eigenfunctions’][0]为ray_out[‘angular orders’]列表中第一个振型的本征函数W分量。
- eigenfunctions_dr :本征函数的导数
- radius eigenfunctions对应的半径列表
- phase velocities
- group velocities
- gamma
- Q
- epsilons
- polynomial order 多项式
输出本征函数和振型信息的函数示例:
Love_output.py
1 | from specnm import love |
计算球型振型(l=0)相关信息
由于l=0时称为radial mode,因此单独计算。相比于Love,其没有lmax选项;没有相速度和群速度输出。
1 | from specnm import rayleigh |
radial_problem
函数只有两个参数:fmin
和fmax
- fmin 浮点型 最小输出频率
- fmax 浮点型 最大输出频率
- attentuation_mode 字符串格式 默认为None, 可以输入’elastic’。
- multishift_kwargs 字典格式 目前未知,官方介绍:additional arguments for the multishift
输出本征函数和振型信息的函数示例:
Rayleigh_output.py
1 | from specnm import radial |
计算球型振型相关信息
有两个函数:
- rayleigh 不考虑重力影响,本征函数具有U、V分量。
- rayleigh_fg 计算具有full gravity的球型振型,本征函数具有U、V、P分量。
rayleigh
1 | from specnm import rayleigh |
ray_out为存储相关振型信息的字典,其中:
- angular orders
- wave numbers
- frequencies
- angular frequencies :2pifrequencies
- eigenfunctions :为一个二维列表,每一个列表为对应频率振型的本征函数,即ray_out[‘eigenfunctions’][0]为ray_out[‘angular orders’]列表中第一个振型的本征函数的两个分量。其中,两个分量按照顺序排列索引分别为:0、2、4……为U分量,1、3、5……为V分量。
- U_eigen_funi = eigenfunctions[i][0::2][0:] 获取U分量
- V_eigen_funi = eigenfunctions[i][1::2][0:] 获取V分量
注意:官方test中去除了第一个数值(radius=0)的本征函数数值,但是radius是从0开始,因此不知其去除的含义。如下方式获取某一振型两个分量的本征函数。i
为angular orders
中的振型索引,[0::2]
表示从第0个开始至末尾获取数据,步长为2;[0:]
表示对获取到的本征函数进行切片,下文中未进行切片,但是官方test中去除了第一个数据,因此使用[1:]
,未知原因。
- eigenfunctions_dr :本征函数的导数
- radius eigenfunctions对应的半径列表
- phase velocities
- group velocities
- gamma
- Q
- epsilons
- polynomial order 多项式
输出本征函数和振型信息的函数示例:
修改日志:
2024.6.18 修改了地球模型需要去除不存在的${1}$S${1}$振型的问题
Rayleigh_output.py
1 | from specnm import love |
rayleigh_fg
同rayleigh
,eigenfunctions的索引不同:
0、3、6……为U分量,1、4、7……为V分量,2、5、8为P分量。
使用上述函数输出振型信息
输出内容为:振型相关信息、每个振型的本征函数文件、基阶振型的三分量本征函数图,每个分量保存在对应的output_dir(输出路径)中:例如W分量保存在Love_output
文件夹下。
先将上述函数保存到相应的py文件中,在目录下创建use.py
文件,即可。
注意:提前在输出路径下创建好output_dir以及在output_dir下创建文件夹:eigenfunctions、eigenfunctions_dr。
1 | from Love_output import Love_output |
绘制地震图
设置震源和台站信息
使用instaseis包中的Source、Receiver函数:
使用Source模块,使用矩张量信息定义震源参数。
示例:
1 | from instaseis import Source, Receiver |
创建或读取振型数据文件:
创建文件
使用seismogram模块中的mode_database模块的compute函数创建mode数据文件:
1 | import os |
读取文件
如果已经计算好模型信息文件,可以直接读取,省去计算过程。可以使用mode_database模块的read()函数读取数据:
1 | tmpdir = '/home/shizhiyuanubuntu/PycharmProjects/Seismology/seismogram_make/data' |
获取地震图并保存在当前目录
使用mode_database模块创建的对象mdb中的属性get_seismogram函数创建地震图:
其中
1 | get_seismograms(source, receiver, mode_types='TRS', dt=1., nt=3600, t0=None, kind='displacement', seismometer_response=False, flattening=0.) |
函数中的参数:
- source 上述instaseis设置的震源信息
- receiver 上述instaseis设置的台站信息
- mode_types 使用的振型类型,一般包括:
- T 环型振型
- S 球型振型
- R l=0时的球型振型
- dt 地震图时间间隔,采样率的倒数
- nt 地震图采样点数
- t0 地震图起始时间,默认为1970年
- kind 地震图类型
- displacement
- velocity
- acceleration
- seismometer_response 是否加入仪器响应
- flattening 存疑 ?展平变换
1 | streams = mdb.get_seismograms(source=src, receiver=rec, mode_types='TRS', dt=1., nt=30000, t0=None, kind='velocity', seismometer_response=False, flattening=0.) |
streams存在属性select(channel=‘XZ’)
可以选择不同的通道。streams有五个通道,分别为:XZ、XN、XE、XR、XT。