initial upload
This commit is contained in:
BIN
examples/.DS_Store
vendored
Normal file
BIN
examples/.DS_Store
vendored
Normal file
Binary file not shown.
7
examples/clean_examples.sh
Executable file
7
examples/clean_examples.sh
Executable file
@@ -0,0 +1,7 @@
|
||||
rm -r ./*/OUTPUT_FILES
|
||||
rm ./*/*.dat
|
||||
rm ./*/*.h5
|
||||
rm ./*/*.txt
|
||||
rm ./*/params_log.yaml
|
||||
rm -r ./*/OUTPUT_FILES*
|
||||
rm ./*/*/*.h5
|
||||
@@ -0,0 +1,215 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-10, 50] # depth in km
|
||||
min_max_lat: [0, 2] # latitude in degree
|
||||
min_max_lon: [0, 2] # longitude in degree
|
||||
n_rtp: [61, 61, 61] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: OUTPUT_FILES/OUTPUT_FILES_signal/src_rec_file_forward_noisy.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver (only valid for regional source and receiver, those of tele remain unchanged)
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_init_N61_61_61.h5 # path to initial model file
|
||||
# model_1d_name: dummy_model_1d_name # 1D model name used in teleseismic 2D solver (iasp91, ak135, user_defined is available), defined in include/1d_model.h
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
nproc_sub: 1 # number of processors for sweep parallelization (parallel the fast sweep method)
|
||||
use_gpu: false # true if use gpu (EXPERIMENTAL)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_inv # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_source_field: false # True: output the traveltime field and adjoint field of all sources at each iteration. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_kernel: false # True: output sensitivity kernel and kernel density. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_final_model: true # True: output merged final model. This file can be used as the input model for TomoATT. Default: true. File: 'model_final.h5'.
|
||||
output_middle_model: false # True: output merged intermediate models during inversion. This file can be used as the input model for TomoATT. Default: false. File: 'middle_model_step_XXXX.h5'
|
||||
output_in_process: false # True: output at each inv iteration, otherwise, only output step 0, Niter-1, Niter. Default: true. File: 'out_data_sim_group_0'.
|
||||
output_in_process_data: false # True: output src_rec_file at each inv iteration, otherwise, only output step 0, Niter-2, Niter-1. Default: true. File: 'src_rec_file_step_XXXX.dat'
|
||||
single_precision_output: false # True: output results in single precision. Default: false.
|
||||
verbose_output_level: 0 # output internal parameters, (to do).
|
||||
output_file_format: 0 # 0: hdf5, 1: ascii
|
||||
|
||||
# output files:
|
||||
# File: 'out_data_grid.h5'. Keys: ['Mesh']['elem_conn'], element index;
|
||||
# ['Mesh']['node_coords_p'], phi coordinates of nodes;
|
||||
# ['Mesh']['node_coords_t'], theta coordinates of nodes;
|
||||
# ['Mesh']['node_coords_r'], r coordinates of nodes;
|
||||
# ['Mesh']['node_coords_x'], phi coordinates of elements;
|
||||
# ['Mesh']['node_coords_y'], theta coordinates of elements;
|
||||
# ['Mesh']['node_coords_z'], r coordinates of elements;
|
||||
# File: 'out_data_sim_group_0'. Keys: ['model']['vel_inv_XXXX'], velocity model at iteration XXXX;
|
||||
# ['model']['xi_inv_XXXX'], xi model at iteration XXXX;
|
||||
# ['model']['eta_inv_XXXX'], eta model at iteration XXXX
|
||||
# ['model']['Ks_inv_XXXX'], sensitivity kernel related to slowness at iteration XXXX
|
||||
# ['model']['Kxi_inv_XXXX'], sensitivity kernel related to xi at iteration XXXX
|
||||
# ['model']['Keta_inv_XXXX'], sensitivity kernel related to eta at iteration XXXX
|
||||
# ['model']['Ks_density_inv_XXXX'], kernel density of Ks at iteration XXXX
|
||||
# ['model']['Kxi_density_inv_XXXX'], kernel density of Kxi at iteration XXXX
|
||||
# ['model']['Keta_density_inv_XXXX'], kernel density of Keta at iteration XXXX
|
||||
# ['model']['Ks_over_Kden_inv_XXXX'], slowness kernel over kernel density at iteration XXXX
|
||||
# ['model']['Kxi_over_Kden_inv_XXXX'], xi kernel over kernel density at iteration XXXX
|
||||
# ['model']['Keta_over_Kden_inv_XXXX'], eta kernel over kernel density at iteration XXXX
|
||||
# ['model']['Ks_update_inv_XXXX'], slowness kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Kxi_update_inv_XXXX'], xi kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Keta_update_inv_XXXX'], eta kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['1dinv']['vel_1dinv_inv_XXXX'], 2d velocity model at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['r_1dinv'], r coordinates (depth), in 1d inversion mode
|
||||
# ['1dinv']['t_1dinv'], t coordinates (epicenter distance), in 1d inversion mode
|
||||
# File: 'src_rec_file_step_XXXX.dat' or 'src_rec_file_forward.dat'. The synthetic traveltime data file.
|
||||
# File: 'final_model.h5'. Keys: ['eta'], ['xi'], ['vel'], the final model.
|
||||
# File: 'middle_model_step_XXXX.h5'. Keys: ['eta'], ['xi'], ['vel'], the model at step XXXX.
|
||||
# File: 'inversion_grid.txt'. The location of inversion grid nodes
|
||||
# File: 'objective_function.txt'. The objective function value at each iteration
|
||||
# File: 'out_data_sim_group_X'. Keys: ['src_YYYY']['time_field_inv_XXXX'], traveltime field of source YYYY at iteration XXXX;
|
||||
# ['src_YYYY']['adjoint_field_inv_XXXX'], adjoint field of source YYYY at iteration XXXX;
|
||||
# ['1dinv']['time_field_1dinv_YYYY_inv_XXXX'], 2d traveltime field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['adjoint_field_1dinv_YYYY_inv_XXXX'], 2d adjoint field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
# 4 for 1d model inversion
|
||||
run_mode: 1
|
||||
|
||||
have_tele_data: false # An error will be reported if false but source out of study region is used. Default: false.
|
||||
|
||||
###################################################
|
||||
# model update parameters setting #
|
||||
###################################################
|
||||
model_update:
|
||||
max_iterations: 40 # maximum number of inversion iterations
|
||||
optim_method: 0 # optimization method. 0 : grad_descent, 1 : halve-stepping, 2 : lbfgs (EXPERIMENTAL)
|
||||
|
||||
#common parameters for all optim methods
|
||||
step_length: 0.02 # the initial step length of model perturbation. 0.01 means maximum 1% perturbation for each iteration.
|
||||
|
||||
# parameters for optim_method 0 (gradient_descent)
|
||||
optim_method_0:
|
||||
step_method: 1 # the method to modulate step size. 0: according to objective function; 1: according to gradient direction
|
||||
# if step_method:0. if objective function increase, step size -> step length * step_length_decay.
|
||||
step_length_decay: 0.9 # default: 0.9
|
||||
# if step_method:1. if the angle between the current and the previous gradients is greater than step_length_gradient_angle, step size -> step length * step_length_change[0].
|
||||
# otherwise, step size -> step length * step_length_change[1].
|
||||
step_length_gradient_angle: 120 # default: 120.0
|
||||
step_length_change: [0.5, 1.2] # default: [0.5,1.2]
|
||||
# Kdensity_coe is used to rescale the final kernel: kernel -> kernel / pow(density of kernel, Kdensity_coe). if Kdensity_coe > 0, the region with less data will be enhanced during the inversion
|
||||
# e.g., if Kdensity_coe = 0, kernel remains upchanged; if Kdensity_coe = 1, kernel is fully normalized. 0.5 or less is recommended if really required.
|
||||
Kdensity_coe: 0 # default: 0.0, limited range: 0.0 - 0.95
|
||||
|
||||
# smoothing
|
||||
smoothing:
|
||||
smooth_method: 0 # 0: multiparametrization, 1: laplacian smoothing (EXPERIMENTAL)
|
||||
l_smooth_rtp: [1, 1, 1] # smoothing coefficients for laplacian smoothing
|
||||
|
||||
# parameters for smooth method 0 (multigrid model parametrization)
|
||||
# inversion grid can be viewed in OUTPUT_FILES/inversion_grid.txt
|
||||
n_inversion_grid: 5 # number of inversion grid sets
|
||||
|
||||
uniform_inv_grid_dep: false # true if use uniform inversion grid for dep, false if use flexible inversion grid
|
||||
uniform_inv_grid_lat: true # true if use uniform inversion grid for lat, false if use flexible inversion grid
|
||||
uniform_inv_grid_lon: true # true if use uniform inversion grid for lon, false if use flexible inversion grid
|
||||
|
||||
# -------------- uniform inversion grid setting --------------
|
||||
# settings for uniform inversion grid
|
||||
n_inv_dep_lat_lon: [12, 9, 9] # number of the base inversion grid points
|
||||
min_max_dep_inv: [-10, 50] # depth in km (Radius of the earth is defined in config.h/R_earth)
|
||||
min_max_lat_inv: [0, 2] # latitude in degree
|
||||
min_max_lon_inv: [0, 2] # longitude in degree
|
||||
|
||||
# -------------- flexible inversion grid setting --------------
|
||||
# settings for flexible inversion grid
|
||||
dep_inv: [-10, 0, 10, 20, 30, 40, 50, 60] # inversion grid for vel in depth (km)
|
||||
lat_inv: [30, 30.2, 30.4, 30.6, 30.8, 31, 31.2, 31.4, 31.6, 31.8, 32] # inversion grid for vel in latitude (degree)
|
||||
lon_inv: [30, 30.2, 30.4, 30.6, 30.8, 31, 31.2, 31.4, 31.6, 31.8, 32] # inversion grid for vel in longitude (degree)
|
||||
trapezoid: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
|
||||
|
||||
# Carefully change trapezoid and trapezoid_ani, if you really want to use trapezoid inversion grid, increasing the inversion grid spacing with depth to account for the worse data coverage in greater depths.
|
||||
# The trapezoid_ inversion grid with index (i,j,k) in longitude, latitude, and depth is defined as:
|
||||
# if dep_inv[k] < trapezoid[1], lon = lon_inv[i];
|
||||
# lat = lat_inv[j];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[1] <= dep_inv[k] < trapezoid[2], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[2] <= dep_inv[k], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# The shape of trapezoid inversion gird (x) looks like:
|
||||
#
|
||||
# lon_inv[0] [1] [2] [3] [4]
|
||||
# |<-------- (lon_inv[end] - lon_inv[0]) ---->|
|
||||
# dep_inv[0] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[1] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[2] = trapezoid[1] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[3] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[4] = trapezoid[2] / x x x x x \
|
||||
# | |
|
||||
# dep_inv[5] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[6] | x x x x x |
|
||||
# |<---- trapezoid[0]* (lon_inv[end] - lon_inv[0]) ------>|
|
||||
|
||||
|
||||
# In the following data subsection, XXX_weight means a weight is assigned to the data, influencing the objective function and gradient
|
||||
# XXX_weight : [d1,d2,w1,w2] means:
|
||||
# if XXX < d1, weight = w1
|
||||
# if d1 <= XXX < d2, weight = w1 + (XXX-d1)/(d2-d1)*(w2-w1), (linear interpolation)
|
||||
# if d2 <= XXX , weight = w2
|
||||
# You can easily set w1 = w2 = 1.0 to normalize the weight related to XXX.
|
||||
# -------------- using absolute traveltime data --------------
|
||||
abs_time:
|
||||
use_abs_time: true # 'true' for using absolute traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the absolute traveltime residual (second) = abs(t^{obs}_{n,i} - t^{syn}_{n,j})
|
||||
distance_weight: [100, 200, 1, 1] # XXX is epicenter distance (km) between the source and receiver related to the data
|
||||
|
||||
# -------------- using common source differential traveltime data --------------
|
||||
cs_dif_time:
|
||||
use_cs_time: false # 'true' for using common source differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the common source differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{n,j} - t^{syn}_{n,i} + t^{syn}_{n,j}).
|
||||
azimuthal_weight: [15, 30, 1, 1] # XXX is the azimuth difference between two separate stations related to the common source.
|
||||
|
||||
# -------------- using common receiver differential traveltime data --------------
|
||||
cr_dif_time:
|
||||
use_cr_time: false # 'true' for using common receiver differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the common receiver differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{m,i} - t^{syn}_{n,i} + t^{syn}_{m,i})
|
||||
azimuthal_weight: [15, 30, 1, 1] # XXX is the azimuth difference between two separate sources related to the common receiver.
|
||||
|
||||
# -------------- global weight of different types of data (to balance the weight of different data) --------------
|
||||
global_weight:
|
||||
balance_data_weight: false # yes: over the total weight of the each type of the data. no: use original weight (below weight for each type of data needs to be set)
|
||||
abs_time_weight: 1 # weight of absolute traveltime data after balance, default: 1.0
|
||||
cs_dif_time_local_weight: 1 # weight of common source differential traveltime data after balance, default: 1.0
|
||||
cr_dif_time_local_weight: 1 # weight of common receiver differential traveltime data after balance, default: 1.0
|
||||
teleseismic_weight: 1 # weight of teleseismic data after balance, default: 1.0 (exclude in this version)
|
||||
|
||||
# -------------- inversion parameters --------------
|
||||
update_slowness : true # update slowness (velocity) or not. default: true
|
||||
update_azi_ani : true # update azimuthal anisotropy (xi, eta) or not. default: false
|
||||
@@ -0,0 +1,50 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-10, 50] # depth in km
|
||||
min_max_lat: [0, 2] # latitude in degree
|
||||
min_max_lon: [0, 2] # longitude in degree
|
||||
n_rtp: [61, 61, 61] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: 1_src_rec_files/src_rec_config.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_ckb_N61_61_61.h5 # path to initial model file
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_signal # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_final_model: true # output merged final model (final_model.h5) or not.
|
||||
output_in_process: false # output model at each inv iteration or not.
|
||||
output_in_process_data: false # output src_rec_file at each inv iteration or not.
|
||||
output_file_format: 0
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
run_mode: 0
|
||||
29
examples/eg1_seismic_tomography/README.md
Normal file
29
examples/eg1_seismic_tomography/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# seismic tomography
|
||||
|
||||
This is a toy model to invert traveltimes for Vp and anisotropy (Figure 8c.)
|
||||
|
||||
Reference:
|
||||
[1] J. Chen, M. Nagaso, M. Xu, and P. Tong, TomoATT: An open-source package for Eikonal equation-based adjoint-state traveltime tomography for seismic velocity and azimuthal anisotropy, submitted.
|
||||
https://doi.org/10.48550/arXiv.2412.00031
|
||||
|
||||
Python modules are required to initiate the inversion and to plot final results:
|
||||
- h5py
|
||||
- PyTomoAT
|
||||
- Pygmt
|
||||
- gmt
|
||||
|
||||
Run this example:
|
||||
|
||||
1. Run bash script `bash run_this_example.sh` to execute the test.
|
||||
|
||||
2. After inversion, run `plot_output.py` to plot the results.
|
||||
|
||||
The initial and true models:
|
||||
|
||||

|
||||
|
||||
The inversion result:
|
||||
|
||||

|
||||
|
||||
|
||||
16
examples/eg1_seismic_tomography/assign_gaussian_noise.py
Normal file
16
examples/eg1_seismic_tomography/assign_gaussian_noise.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
|
||||
def assign_noise_to_src_rec_file(in_fname, out_fname, noise_level=0.1):
|
||||
sr = SrcRec.read(in_fname)
|
||||
sr.add_noise(noise_level)
|
||||
sr.write(out_fname)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
in_fname = "OUTPUT_FILES/OUTPUT_FILES_signal/src_rec_file_forward.dat" # input source receiver file
|
||||
out_fname = "OUTPUT_FILES/OUTPUT_FILES_signal/src_rec_file_forward_noisy.dat" # output source receiver file
|
||||
sigma = 0.1 # noise level in seconds
|
||||
assign_noise_to_src_rec_file(in_fname, out_fname, noise_level=sigma)
|
||||
|
||||
|
||||
|
||||
250
examples/eg1_seismic_tomography/plot_output.py
Normal file
250
examples/eg1_seismic_tomography/plot_output.py
Normal file
@@ -0,0 +1,250 @@
|
||||
# %%
|
||||
import pygmt
|
||||
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
|
||||
|
||||
import os
|
||||
|
||||
# %%
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.data import ATTData
|
||||
import numpy as np
|
||||
|
||||
# %%
|
||||
# read models
|
||||
|
||||
Ngrid = [61,61,61]
|
||||
data_file = '2_models/model_init_N%d_%d_%d.h5'%(Ngrid[0],Ngrid[1],Ngrid[2])
|
||||
par_file = '3_input_params/input_params_signal.yaml'
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
initial_model = model.to_xarray()
|
||||
|
||||
data_file = '2_models/model_ckb_N%d_%d_%d.h5'%(Ngrid[0],Ngrid[1],Ngrid[2])
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
ckb_model = model.to_xarray()
|
||||
|
||||
# initial model
|
||||
depth = 10.0
|
||||
vel_init = initial_model.interp_dep(depth, field='vel')
|
||||
start = [1.25,0]; end = [1.25,2]
|
||||
vel_init_sec = initial_model.interp_sec(start, end, field='vel', val = 1)
|
||||
|
||||
# checkerboard model
|
||||
vel_ckb = ckb_model.interp_dep(depth, field='vel') # lon = [:,0], lat = [:,1], vel = [:,2]
|
||||
vel_ckb_sec = ckb_model.interp_sec(start, end, field='vel', val = 1)
|
||||
|
||||
# anisotropic arrow
|
||||
samp_interval = 3
|
||||
length = 7
|
||||
width = 0.1
|
||||
ani_thd = 0.02
|
||||
|
||||
ani_ckb_phi = ckb_model.interp_dep(depth, field='phi', samp_interval=samp_interval)
|
||||
ani_ckb_epsilon = ckb_model.interp_dep(depth, field='epsilon', samp_interval=samp_interval)
|
||||
ani_ckb = np.hstack([ani_ckb_phi, ani_ckb_epsilon[:,2].reshape(-1, 1)*length, np.ones((ani_ckb_epsilon.shape[0],1))*width]) # lon, lat, angle, length, width
|
||||
idx = np.where(ani_ckb_epsilon[:,2] > ani_thd)
|
||||
ani_ckb = ani_ckb[idx[0],:]
|
||||
|
||||
try:
|
||||
os.mkdir('img')
|
||||
except:
|
||||
pass
|
||||
|
||||
# %%
|
||||
# read src_rec_file for data
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
|
||||
sr = SrcRec.read('1_src_rec_files/src_rec_config.dat')
|
||||
station = sr.receivers[['stlo','stla','stel']].values.T
|
||||
true_loc = sr.sources[['evlo','evla','evdp']].values.T
|
||||
earthquake = true_loc
|
||||
|
||||
# %%
|
||||
# categorize earthquakes
|
||||
ev_idx1 = []
|
||||
ev_idx2 = []
|
||||
ev_idx3 = []
|
||||
for i in range(earthquake.shape[1]):
|
||||
dep = earthquake[2,i]
|
||||
if dep < 15:
|
||||
ev_idx1.append(i)
|
||||
elif dep < 25:
|
||||
ev_idx2.append(i)
|
||||
elif dep < 35:
|
||||
ev_idx3.append(i)
|
||||
|
||||
# %%
|
||||
# plot the checkerboard model
|
||||
fig = pygmt.Figure()
|
||||
|
||||
region = [0,2,0,2]
|
||||
frame = ["xa1","ya1","nSWe"]
|
||||
projection = "M10c"
|
||||
spacing = 0.04
|
||||
|
||||
vel_range = 20
|
||||
|
||||
# -------------- initial model and earthquake location --------------
|
||||
fig.basemap(region=region, frame=["xa1","ya1","+tInitial model and locations"], projection=projection)
|
||||
# velocity perturbation
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-vel_range, vel_range], background=True, reverse=False)
|
||||
x = vel_init[:,0]; y = vel_init[:,1]; value = (vel_init[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(grid = grid)
|
||||
# earthquakes
|
||||
fig.plot(x = true_loc[0,ev_idx1], y = true_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = true_loc[0,ev_idx2], y = true_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = true_loc[0,ev_idx3], y = true_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
# stations
|
||||
fig.plot(x = station[0,:], y = station[1,:], style = "t0.4c", fill = "blue", pen = "black", label = "Station")
|
||||
|
||||
# # anisotropic arrow
|
||||
# fig.plot(ani_ckb, style='j', fill='yellow1', pen='0.5p,black')
|
||||
|
||||
fig.shift_origin(xshift=11)
|
||||
|
||||
fig.basemap(region=[0,40,0,2], frame=["xa20+lDepth (km)","ya1","Nswe"], projection="X2c/10c")
|
||||
x = vel_init_sec[:,3]; y = vel_init_sec[:,1]; value = (vel_init_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="1/0.04",region=[0,40,0,2])
|
||||
fig.grdimage(grid = grid)
|
||||
|
||||
# earthquakes
|
||||
fig.plot(x = true_loc[2,ev_idx1], y = true_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = true_loc[2,ev_idx2], y = true_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = true_loc[2,ev_idx3], y = true_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
|
||||
fig.shift_origin(xshift=4)
|
||||
|
||||
|
||||
|
||||
|
||||
# -------------- checkerboard model --------------
|
||||
fig.basemap(region=region, frame=["xa1","ya1","+tTrue model and locations"], projection=projection)
|
||||
# velocity perturbation
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-vel_range, vel_range], background=True, reverse=False)
|
||||
x = vel_ckb[:,0]; y = vel_ckb[:,1]; value = (vel_ckb[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(grid = grid)
|
||||
# earthquakes
|
||||
fig.plot(x = earthquake[0,ev_idx1], y = earthquake[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = earthquake[0,ev_idx2], y = earthquake[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = earthquake[0,ev_idx3], y = earthquake[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
# stations
|
||||
# fig.plot(x = loc_st[0,:], y = loc_st[1,:], style = "t0.4c", fill = "blue", pen = "black", label = "Station")
|
||||
|
||||
# anisotropic arrow
|
||||
fig.plot(ani_ckb, style='j', fill='yellow1', pen='0.5p,black')
|
||||
|
||||
fig.shift_origin(xshift=11)
|
||||
|
||||
fig.basemap(region=[0,40,0,2], frame=["xa20+lDepth (km)","ya1","Nswe"], projection="X2c/10c")
|
||||
x = vel_ckb_sec[:,3]; y = vel_ckb_sec[:,1]; value = (vel_ckb_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="1/0.04",region=[0,40,0,2])
|
||||
fig.grdimage(grid = grid)
|
||||
|
||||
# earthquakes
|
||||
fig.plot(x = earthquake[2,ev_idx1], y = earthquake[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = earthquake[2,ev_idx2], y = earthquake[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = earthquake[2,ev_idx3], y = earthquake[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
|
||||
# ------------------- colorbar -------------------
|
||||
fig.shift_origin(xshift=-11, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a%f"%(vel_range),"x+ldlnVp (%)"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.shift_origin(xshift=6, yshift=-1)
|
||||
fig.basemap(region=[0,1,0,1], frame=["wesn"], projection="X6c/1.5c")
|
||||
ani = [
|
||||
[0.2, 0.6, 45, 0.02*length, width], # lon, lat, phi, epsilon, size
|
||||
[0.5, 0.6, 45, 0.05*length, width],
|
||||
[0.8, 0.6, 45, 0.10*length, width],
|
||||
]
|
||||
fig.plot(ani, style='j', fill='yellow1', pen='0.5p,black')
|
||||
fig.text(text=["0.02", "0.05", "0.10"], x=[0.2,0.5,0.8], y=[0.2]*3, font="16p,Helvetica", justify="CM")
|
||||
fig.shift_origin(xshift= 11, yshift=2.5)
|
||||
|
||||
fig.show()
|
||||
fig.savefig('img/model_setting.png', dpi=300)
|
||||
|
||||
# %%
|
||||
# plot the inversion result
|
||||
|
||||
# read models
|
||||
tag = "inv"
|
||||
data_file = "OUTPUT_FILES/OUTPUT_FILES_%s/final_model.h5"%(tag)
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
inv_model = model.to_xarray()
|
||||
vel_inv = inv_model.interp_dep(depth, field='vel') # lon = [:,0], lat = [:,1], vel = [:,2]
|
||||
x = vel_inv[:,0]; y = vel_inv[:,1]; value = (vel_inv[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
vel_inv_sec = inv_model.interp_sec(start, end, field='vel', val = 1)
|
||||
x_sec = vel_inv_sec[:,3]; y_sec = vel_inv_sec[:,1]; value_sec = (vel_inv_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
|
||||
ani_inv_phi = inv_model.interp_dep(depth, field='phi', samp_interval=samp_interval)
|
||||
ani_inv_epsilon = inv_model.interp_dep(depth, field='epsilon', samp_interval=samp_interval)
|
||||
ani_inv = np.hstack([ani_inv_phi, ani_inv_epsilon[:,2].reshape(-1, 1)*length, np.ones((ani_inv_epsilon.shape[0],1))*width]) # lon, lat, angle, length, width
|
||||
idx = np.where(ani_inv_epsilon[:,2] > ani_thd)
|
||||
ani_inv = ani_inv[idx[0],:]
|
||||
|
||||
# plot the inversion result
|
||||
|
||||
fig = pygmt.Figure()
|
||||
|
||||
region = [0,2,0,2]
|
||||
frame = ["xa1","ya1","+tInversion results"]
|
||||
projection = "M10c"
|
||||
spacing = 0.04
|
||||
|
||||
vel_range = 20
|
||||
|
||||
# -------------- checkerboard model --------------
|
||||
fig.basemap(region=region, frame=frame, projection=projection)
|
||||
# velocity perturbation
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-vel_range, vel_range], background=True, reverse=False)
|
||||
x = vel_inv[:,0]; y = vel_inv[:,1]; value = (vel_inv[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(grid = grid)
|
||||
# # earthquakes
|
||||
# fig.plot(x = earthquake[0,ev_idx1], y = earthquake[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
# fig.plot(x = earthquake[0,ev_idx2], y = earthquake[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
# fig.plot(x = earthquake[0,ev_idx3], y = earthquake[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
# stations
|
||||
# fig.plot(x = loc_st[0,:], y = loc_st[1,:], style = "t0.4c", fill = "blue", pen = "black", label = "Station")
|
||||
|
||||
# anisotropic arrow
|
||||
fig.plot(ani_inv, style='j', fill='yellow1', pen='0.5p,black')
|
||||
|
||||
fig.shift_origin(xshift=11)
|
||||
|
||||
fig.basemap(region=[0,40,0,2], frame=["xa20+lDepth (km)","ya1","Nswe"], projection="X2c/10c")
|
||||
x = vel_inv_sec[:,3]; y = vel_inv_sec[:,1]; value = (vel_inv_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="1/0.04",region=[0,40,0,2])
|
||||
fig.grdimage(grid = grid)
|
||||
|
||||
# # earthquakes
|
||||
# fig.plot(x = earthquake[2,ev_idx1], y = earthquake[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
# fig.plot(x = earthquake[2,ev_idx2], y = earthquake[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
# fig.plot(x = earthquake[2,ev_idx3], y = earthquake[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
# ------------------- colorbar -------------------
|
||||
fig.shift_origin(xshift=-11, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a%f"%(vel_range),"x+ldlnVp (%)"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.shift_origin(xshift=6, yshift=-1)
|
||||
fig.basemap(region=[0,1,0,1], frame=["wesn"], projection="X6c/1.5c")
|
||||
ani = [
|
||||
[0.2, 0.6, 45, 0.02*length, width], # lon, lat, phi, epsilon, size
|
||||
[0.5, 0.6, 45, 0.05*length, width],
|
||||
[0.8, 0.6, 45, 0.10*length, width],
|
||||
]
|
||||
fig.plot(ani, style='j', fill='yellow1', pen='0.5p,black')
|
||||
fig.text(text=["0.02", "0.05", "0.10"], x=[0.2,0.5,0.8], y=[0.2]*3, font="16p,Helvetica", justify="CM")
|
||||
fig.shift_origin(xshift= 11, yshift=2.5)
|
||||
|
||||
|
||||
fig.show()
|
||||
fig.savefig('img/model_%s.png'%(tag), dpi=300)
|
||||
|
||||
|
||||
63
examples/eg1_seismic_tomography/prepare_input_files.py
Normal file
63
examples/eg1_seismic_tomography/prepare_input_files.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# download src_ref_files from Zenodo
|
||||
import os
|
||||
import numpy as np
|
||||
import sys
|
||||
try:
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.checkerboard import Checker
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
except:
|
||||
print("ERROR: ATTModel not found. Please install pytomoatt first."
|
||||
"See https://tomoatt.github.io/PyTomoATT/installation.html for details.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
class BuildInitialModel():
|
||||
def __init__(self, par_file="./3_input_params/input_params_signal.yaml", output_dir="2_models"):
|
||||
"""
|
||||
Build initial model for tomography inversion
|
||||
"""
|
||||
self.am = ATTModel(par_file)
|
||||
self.output_dir = output_dir
|
||||
|
||||
def build_initial_model(self, vel_min=5.0, vel_max=8.0):
|
||||
"""
|
||||
Build initial model for tomography inversion
|
||||
"""
|
||||
self.am.vel[self.am.depths < 0, :, :] = vel_min
|
||||
idx = np.where((0 <= self.am.depths) & (self.am.depths < 40.0))[0]
|
||||
self.am.vel[idx, :, :] = np.linspace(vel_min, vel_max, idx.size)[::-1][:, np.newaxis, np.newaxis]
|
||||
self.am.vel[self.am.depths >= 40.0, :, :] = vel_max
|
||||
|
||||
|
||||
def build_ckb_model(output_dir="2_models"):
|
||||
cbk = Checker(f'{output_dir}/model_init_N61_61_61.h5', para_fname="./3_input_params/input_params_signal.yaml")
|
||||
cbk.checkerboard(
|
||||
n_pert_x=2, n_pert_y=2, n_pert_z=2,
|
||||
pert_vel=0.2, pert_ani=0.1, ani_dir=60.0,
|
||||
lim_x=[0.5, 1.5], lim_y=[0.5, 1.5], lim_z=[0, 40]
|
||||
)
|
||||
cbk.write(f'{output_dir}/model_ckb_N61_61_61.h5')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# download src_rec_config.dat
|
||||
url = 'https://zenodo.org/records/14053821/files/src_rec_config.dat'
|
||||
path = "1_src_rec_files/src_rec_config.dat"
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
if not os.path.exists(path):
|
||||
sr = SrcRec.read(url)
|
||||
sr.write(path)
|
||||
|
||||
# build initial model
|
||||
output_dir = "2_models"
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
bim = BuildInitialModel(output_dir=output_dir)
|
||||
bim.build_initial_model()
|
||||
bim.am.write('{}/model_init_N{:d}_{:d}_{:d}.h5'.format(bim.output_dir, *bim.am.n_rtp))
|
||||
|
||||
# build ckb model
|
||||
build_ckb_model(output_dir)
|
||||
|
||||
|
||||
|
||||
29
examples/eg1_seismic_tomography/run_this_example.sh
Normal file
29
examples/eg1_seismic_tomography/run_this_example.sh
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
# Step 1: Generate necessary input files
|
||||
python prepare_input_files.py
|
||||
|
||||
# Step 2: Run forward modeling
|
||||
# for WSL
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_signal.yaml
|
||||
# # for Linux
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_signal.yaml
|
||||
# for conda install
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_signal.yaml
|
||||
|
||||
|
||||
# Step 3: Assign data noise to the observational data
|
||||
python assign_gaussian_noise.py
|
||||
|
||||
# Step 4: Do inversion
|
||||
# for WSL
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_inv.yaml
|
||||
# # for Linux
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_inv.yaml
|
||||
# for conda install
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_inv.yaml
|
||||
|
||||
|
||||
# Step 5 (Optional): Plot the results
|
||||
python plot_output.py
|
||||
@@ -0,0 +1,114 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-10, 50] # depth in km
|
||||
min_max_lat: [0, 2] # latitude in degree
|
||||
min_max_lon: [0, 2] # longitude in degree
|
||||
n_rtp: [61, 61, 61] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: OUTPUT_FILES/OUTPUT_FILES_signal/src_rec_file_forward_errloc.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_ckb_N61_61_61.h5 # path to initial model file
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_loc # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_final_model: true # output merged final model (final_model.h5) or not.
|
||||
output_in_process: false # output model at each inv iteration or not.
|
||||
output_in_process_data: false # output src_rec_file at each inv iteration or not.
|
||||
output_file_format: 0
|
||||
|
||||
# output files:
|
||||
# File: 'out_data_grid.h5'. Keys: ['Mesh']['elem_conn'], element index;
|
||||
# ['Mesh']['node_coords_p'], phi coordinates of nodes;
|
||||
# ['Mesh']['node_coords_t'], theta coordinates of nodes;
|
||||
# ['Mesh']['node_coords_r'], r coordinates of nodes;
|
||||
# ['Mesh']['node_coords_x'], phi coordinates of elements;
|
||||
# ['Mesh']['node_coords_y'], theta coordinates of elements;
|
||||
# ['Mesh']['node_coords_z'], r coordinates of elements;
|
||||
# File: 'out_data_sim_group_0'. Keys: ['model']['vel_inv_XXXX'], velocity model at iteration XXXX;
|
||||
# ['model']['xi_inv_XXXX'], xi model at iteration XXXX;
|
||||
# ['model']['eta_inv_XXXX'], eta model at iteration XXXX
|
||||
# ['model']['Ks_inv_XXXX'], sensitivity kernel related to slowness at iteration XXXX
|
||||
# ['model']['Kxi_inv_XXXX'], sensitivity kernel related to xi at iteration XXXX
|
||||
# ['model']['Keta_inv_XXXX'], sensitivity kernel related to eta at iteration XXXX
|
||||
# ['model']['Ks_density_inv_XXXX'], kernel density of Ks at iteration XXXX
|
||||
# ['model']['Kxi_density_inv_XXXX'], kernel density of Kxi at iteration XXXX
|
||||
# ['model']['Keta_density_inv_XXXX'], kernel density of Keta at iteration XXXX
|
||||
# ['model']['Ks_over_Kden_inv_XXXX'], slowness kernel over kernel density at iteration XXXX
|
||||
# ['model']['Kxi_over_Kden_inv_XXXX'], xi kernel over kernel density at iteration XXXX
|
||||
# ['model']['Keta_over_Kden_inv_XXXX'], eta kernel over kernel density at iteration XXXX
|
||||
# ['model']['Ks_update_inv_XXXX'], slowness kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Kxi_update_inv_XXXX'], xi kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Keta_update_inv_XXXX'], eta kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['1dinv']['vel_1dinv_inv_XXXX'], 2d velocity model at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['r_1dinv'], r coordinates (depth), in 1d inversion mode
|
||||
# ['1dinv']['t_1dinv'], t coordinates (epicenter distance), in 1d inversion mode
|
||||
# File: 'src_rec_file_step_XXXX.dat' or 'src_rec_file_forward.dat'. The synthetic traveltime data file.
|
||||
# File: 'final_model.h5'. Keys: ['eta'], ['xi'], ['vel'], the final model.
|
||||
# File: 'middle_model_step_XXXX.h5'. Keys: ['eta'], ['xi'], ['vel'], the model at step XXXX.
|
||||
# File: 'inversion_grid.txt'. The location of inversion grid nodes
|
||||
# File: 'objective_function.txt'. The objective function value at each iteration
|
||||
# File: 'out_data_sim_group_X'. Keys: ['src_YYYY']['time_field_inv_XXXX'], traveltime field of source YYYY at iteration XXXX;
|
||||
# ['src_YYYY']['adjoint_field_inv_XXXX'], adjoint field of source YYYY at iteration XXXX;
|
||||
# ['1dinv']['time_field_1dinv_YYYY_inv_XXXX'], 2d traveltime field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['adjoint_field_1dinv_YYYY_inv_XXXX'], 2d adjoint field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
# 4 for 1d model inversion
|
||||
run_mode: 2
|
||||
|
||||
#################################################
|
||||
# relocation parameters setting #
|
||||
#################################################
|
||||
relocation: # update earthquake hypocenter and origin time (when run_mode : 2 and 3)
|
||||
min_Ndata: 4 # if the number of data of the earthquake is less than <min_Ndata>, the earthquake will not be relocated. defaut value: 4
|
||||
|
||||
# relocation_strategy
|
||||
step_length : 0.01 # initial step length of relocation perturbation. 0.01 means maximum 1% perturbation for each iteration.
|
||||
step_length_decay : 0.9 # if objective function increase, step size -> step length * step_length_decay. default: 0.9
|
||||
rescaling_dep_lat_lon_ortime: [10.0, 15.0, 15.0, 1.0] # The perturbation is related to <rescaling_dep_lat_lon_ortime>. Unit: km,km,km,second
|
||||
max_change_dep_lat_lon_ortime: [10.0, 15.0, 15.0, 1.0] # the change of dep,lat,lon,ortime do not exceed max_change. Unit: km,km,km,second
|
||||
max_iterations : 201 # maximum number of iterations for relocation
|
||||
tol_gradient : 0.0001 # if the norm of gradient is smaller than the tolerance, the iteration of relocation terminates
|
||||
|
||||
# -------------- using absolute traveltime data --------------
|
||||
abs_time:
|
||||
use_abs_time : true # 'yes' for using absolute traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- using common source differential traveltime data --------------
|
||||
cs_dif_time:
|
||||
use_cs_time : false # 'yes' for using common source differential traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- using common receiver differential traveltime data --------------
|
||||
cr_dif_time:
|
||||
use_cr_time : false # 'yes' for using common receiver differential traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
@@ -0,0 +1,50 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-10, 50] # depth in km
|
||||
min_max_lat: [0, 2] # latitude in degree
|
||||
min_max_lon: [0, 2] # longitude in degree
|
||||
n_rtp: [61, 61, 61] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: 1_src_rec_files/src_rec_config.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_ckb_N61_61_61.h5 # path to initial model file
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_signal # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_final_model: true # output merged final model (final_model.h5) or not.
|
||||
output_in_process: false # output model at each inv iteration or not.
|
||||
output_in_process_data: false # output src_rec_file at each inv iteration or not.
|
||||
output_file_format: 0
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
run_mode: 0
|
||||
29
examples/eg2_earthquake_location/README.md
Normal file
29
examples/eg2_earthquake_location/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# earthquake location
|
||||
|
||||
This is a toy model to invert traveltimes for locating earthquakes (Figure 8a.)
|
||||
|
||||
Reference:
|
||||
[1] J. Chen, M. Nagaso, M. Xu, and P. Tong, TomoATT: An open-source package for Eikonal equation-based adjoint-state traveltime tomography for seismic velocity and azimuthal anisotropy, submitted.
|
||||
https://doi.org/10.48550/arXiv.2412.00031
|
||||
|
||||
Python modules are required to initiate the inversion and to plot final results:
|
||||
- h5py
|
||||
- PyTomoAT
|
||||
- Pygmt
|
||||
- gmt
|
||||
|
||||
Run this example:
|
||||
|
||||
1. Run bash script `bash run_this_example.sh` to execute the test.
|
||||
|
||||
2. After inversion, run `plot_output.py` to plot the results.
|
||||
|
||||
The initial and true models:
|
||||
|
||||

|
||||
|
||||
The location results:
|
||||
|
||||

|
||||
|
||||
|
||||
30
examples/eg2_earthquake_location/assign_gaussian_noise.py
Normal file
30
examples/eg2_earthquake_location/assign_gaussian_noise.py
Normal file
@@ -0,0 +1,30 @@
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
|
||||
class AssignNoise:
|
||||
def __init__(self, in_fname, out_fname):
|
||||
self.in_fname = in_fname
|
||||
self.out_fname = out_fname
|
||||
self.sr = SrcRec.read(self.in_fname)
|
||||
|
||||
def assign_noise_for_tt(self, noise_level=0.1):
|
||||
self.sr.add_noise(noise_level)
|
||||
|
||||
def assign_noise_for_src(self, lat_pert=0.1, lon_pert=0.1, dep_pert=10, tau_pert=0.5):
|
||||
self.sr.add_noise_to_source(lat_pert, lon_pert, dep_pert, tau_pert)
|
||||
|
||||
if __name__ == "__main__":
|
||||
in_fname = "OUTPUT_FILES/OUTPUT_FILES_signal/src_rec_file_forward.dat" # input source receiver file
|
||||
out_fname = "OUTPUT_FILES/OUTPUT_FILES_signal/src_rec_file_forward_errloc.dat" # output source receiver file
|
||||
sigma = 0.1 # noise level in seconds
|
||||
lat_pert = 0.1 # assign noise for latitude in degrees
|
||||
lon_pert = 0.1 # assign noise for longitude in degrees
|
||||
dep_pert = 10 # assign noise for depth in km
|
||||
tau_pert = 0.5 # assign noise for origin time in seconds
|
||||
# Initialize the instance
|
||||
an = AssignNoise(in_fname, out_fname)
|
||||
# Assign noise for travel time
|
||||
an.assign_noise_for_tt(sigma)
|
||||
# Assign noise for source
|
||||
an.assign_noise_for_src(lat_pert, lon_pert, dep_pert, tau_pert)
|
||||
# Write the output file
|
||||
an.sr.write(out_fname)
|
||||
254
examples/eg2_earthquake_location/plot_output.py
Normal file
254
examples/eg2_earthquake_location/plot_output.py
Normal file
@@ -0,0 +1,254 @@
|
||||
# %%
|
||||
import pygmt
|
||||
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
|
||||
|
||||
import os
|
||||
|
||||
# %%
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.data import ATTData
|
||||
import numpy as np
|
||||
|
||||
# %%
|
||||
# read models
|
||||
|
||||
Ngrid = [61,61,61]
|
||||
data_file = '2_models/model_init_N%d_%d_%d.h5'%(Ngrid[0],Ngrid[1],Ngrid[2])
|
||||
par_file = '3_input_params/input_params_signal.yaml'
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
initial_model = model.to_xarray()
|
||||
|
||||
data_file = '2_models/model_ckb_N%d_%d_%d.h5'%(Ngrid[0],Ngrid[1],Ngrid[2])
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
ckb_model = model.to_xarray()
|
||||
|
||||
# initial model
|
||||
depth = 10.0
|
||||
vel_init = initial_model.interp_dep(depth, field='vel')
|
||||
start = [1.25,0]; end = [1.25,2]
|
||||
vel_init_sec = initial_model.interp_sec(start, end, field='vel', val = 1)
|
||||
|
||||
# checkerboard model
|
||||
vel_ckb = ckb_model.interp_dep(depth, field='vel') # lon = [:,0], lat = [:,1], vel = [:,2]
|
||||
vel_ckb_sec = ckb_model.interp_sec(start, end, field='vel', val = 1)
|
||||
|
||||
# anisotropic arrow
|
||||
samp_interval = 3
|
||||
length = 7
|
||||
width = 0.1
|
||||
ani_thd = 0.02
|
||||
|
||||
ani_ckb_phi = ckb_model.interp_dep(depth, field='phi', samp_interval=samp_interval)
|
||||
ani_ckb_epsilon = ckb_model.interp_dep(depth, field='epsilon', samp_interval=samp_interval)
|
||||
ani_ckb = np.hstack([ani_ckb_phi, ani_ckb_epsilon[:,2].reshape(-1, 1)*length, np.ones((ani_ckb_epsilon.shape[0],1))*width]) # lon, lat, angle, length, width
|
||||
idx = np.where(ani_ckb_epsilon[:,2] > ani_thd)
|
||||
ani_ckb = ani_ckb[idx[0],:]
|
||||
|
||||
try:
|
||||
os.mkdir('img')
|
||||
except:
|
||||
pass
|
||||
|
||||
# %%
|
||||
# read src_rec_file for data
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
|
||||
sr = SrcRec.read('1_src_rec_files/src_rec_config.dat')
|
||||
station = sr.receivers[['stlo','stla','stel']].values.T
|
||||
true_loc = sr.sources[['evlo','evla','evdp']].values.T
|
||||
earthquake = true_loc
|
||||
|
||||
sr = SrcRec.read('OUTPUT_FILES/OUTPUT_FILES_signal/src_rec_file_forward_errloc.dat')
|
||||
init_loc = sr.sources[['evlo','evla','evdp']].values.T
|
||||
|
||||
# %%
|
||||
# categorize earthquakes
|
||||
ev_idx1 = []
|
||||
ev_idx2 = []
|
||||
ev_idx3 = []
|
||||
for i in range(earthquake.shape[1]):
|
||||
dep = earthquake[2,i]
|
||||
if dep < 15:
|
||||
ev_idx1.append(i)
|
||||
elif dep < 25:
|
||||
ev_idx2.append(i)
|
||||
elif dep < 35:
|
||||
ev_idx3.append(i)
|
||||
|
||||
# %%
|
||||
# plot the model setting
|
||||
fig = pygmt.Figure()
|
||||
|
||||
region = [0,2,0,2]
|
||||
frame = ["xa1","ya1"]
|
||||
projection = "M10c"
|
||||
spacing = 0.04
|
||||
|
||||
vel_range = 20
|
||||
|
||||
# -------------- initial model and earthquake location --------------
|
||||
fig.basemap(region=region, frame=["xa1","ya1","+tInitial model and locations"], projection=projection)
|
||||
# velocity perturbation
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-vel_range, vel_range], background=True, reverse=False)
|
||||
x = vel_ckb[:,0]; y = vel_ckb[:,1]; value = (vel_ckb[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(grid = grid)
|
||||
# earthquakes
|
||||
fig.plot(x = init_loc[0,ev_idx1], y = init_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = init_loc[0,ev_idx2], y = init_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = init_loc[0,ev_idx3], y = init_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
# stations
|
||||
fig.plot(x = station[0,:], y = station[1,:], style = "t0.4c", fill = "blue", pen = "black", label = "Station")
|
||||
|
||||
# anisotropic arrow
|
||||
fig.plot(ani_ckb, style='j', fill='yellow1', pen='0.5p,black')
|
||||
|
||||
fig.shift_origin(xshift=11)
|
||||
|
||||
fig.basemap(region=[0,40,0,2], frame=["xa20+lDepth (km)","ya1","Nswe"], projection="X2c/10c")
|
||||
x = vel_ckb_sec[:,3]; y = vel_ckb_sec[:,1]; value = (vel_ckb_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="1/0.04",region=[0,40,0,2])
|
||||
fig.grdimage(grid = grid)
|
||||
|
||||
# earthquakes
|
||||
fig.plot(x = init_loc[2,ev_idx1], y = init_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = init_loc[2,ev_idx2], y = init_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = init_loc[2,ev_idx3], y = init_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
|
||||
fig.shift_origin(xshift=4)
|
||||
|
||||
|
||||
# -------------- true model and earthquake location --------------
|
||||
fig.basemap(region=region, frame=["xa1","ya1","+tTrue model and locations"], projection=projection)
|
||||
# velocity perturbation
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-vel_range, vel_range], background=True, reverse=False)
|
||||
x = vel_ckb[:,0]; y = vel_ckb[:,1]; value = (vel_ckb[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(grid = grid)
|
||||
# earthquakes
|
||||
fig.plot(x = earthquake[0,ev_idx1], y = earthquake[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = earthquake[0,ev_idx2], y = earthquake[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = earthquake[0,ev_idx3], y = earthquake[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
# stations
|
||||
# fig.plot(x = loc_st[0,:], y = loc_st[1,:], style = "t0.4c", fill = "blue", pen = "black", label = "Station")
|
||||
|
||||
# anisotropic arrow
|
||||
fig.plot(ani_ckb, style='j', fill='yellow1', pen='0.5p,black')
|
||||
|
||||
fig.shift_origin(xshift=11)
|
||||
|
||||
fig.basemap(region=[0,40,0,2], frame=["xa20+lDepth (km)","ya1","Nswe"], projection="X2c/10c")
|
||||
x = vel_ckb_sec[:,3]; y = vel_ckb_sec[:,1]; value = (vel_ckb_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="1/0.04",region=[0,40,0,2])
|
||||
fig.grdimage(grid = grid)
|
||||
|
||||
# earthquakes
|
||||
fig.plot(x = earthquake[2,ev_idx1], y = earthquake[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = earthquake[2,ev_idx2], y = earthquake[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = earthquake[2,ev_idx3], y = earthquake[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
|
||||
# ------------------- colorbar -------------------
|
||||
fig.shift_origin(xshift=-11, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a%f"%(vel_range),"x+ldlnVp (%)"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.shift_origin(xshift=6, yshift=-1)
|
||||
fig.basemap(region=[0,1,0,1], frame=["wesn"], projection="X6c/1.5c")
|
||||
ani = [
|
||||
[0.2, 0.6, 45, 0.02*length, width], # lon, lat, phi, epsilon, size
|
||||
[0.5, 0.6, 45, 0.05*length, width],
|
||||
[0.8, 0.6, 45, 0.10*length, width],
|
||||
]
|
||||
fig.plot(ani, style='j', fill='yellow1', pen='0.5p,black')
|
||||
fig.text(text=["0.02", "0.05", "0.10"], x=[0.2,0.5,0.8], y=[0.2]*3, font="16p,Helvetica", justify="CM")
|
||||
fig.shift_origin(xshift= 11, yshift=2.5)
|
||||
|
||||
fig.show()
|
||||
fig.savefig('img/model_setting.png', dpi=300)
|
||||
|
||||
# %%
|
||||
# plot the location result
|
||||
|
||||
# read models
|
||||
tag = "loc"
|
||||
data_file = "OUTPUT_FILES/OUTPUT_FILES_%s/final_model.h5"%(tag)
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
inv_model = model.to_xarray()
|
||||
vel_inv = inv_model.interp_dep(depth, field='vel') # lon = [:,0], lat = [:,1], vel = [:,2]
|
||||
x = vel_inv[:,0]; y = vel_inv[:,1]; value = (vel_inv[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
vel_inv_sec = inv_model.interp_sec(start, end, field='vel', val = 1)
|
||||
x_sec = vel_inv_sec[:,3]; y_sec = vel_inv_sec[:,1]; value_sec = (vel_inv_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
|
||||
ani_inv_phi = inv_model.interp_dep(depth, field='phi', samp_interval=samp_interval)
|
||||
ani_inv_epsilon = inv_model.interp_dep(depth, field='epsilon', samp_interval=samp_interval)
|
||||
ani_inv = np.hstack([ani_inv_phi, ani_inv_epsilon[:,2].reshape(-1, 1)*length, np.ones((ani_inv_epsilon.shape[0],1))*width]) # lon, lat, angle, length, width
|
||||
idx = np.where(ani_inv_epsilon[:,2] > ani_thd)
|
||||
ani_inv = ani_inv[idx[0],:]
|
||||
|
||||
sr = SrcRec.read('OUTPUT_FILES/OUTPUT_FILES_loc/src_rec_file_reloc_0201.dat')
|
||||
re_loc = sr.sources[['evlo','evla','evdp']].values.T
|
||||
|
||||
# plot the inversion result
|
||||
|
||||
fig = pygmt.Figure()
|
||||
|
||||
region = [0,2,0,2]
|
||||
frame = ["xa1","ya1","+tLocation results"]
|
||||
projection = "M10c"
|
||||
spacing = 0.04
|
||||
|
||||
vel_range = 20
|
||||
|
||||
# -------------- checkerboard model --------------
|
||||
fig.basemap(region=region, frame=frame, projection=projection)
|
||||
# velocity perturbation
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-vel_range, vel_range], background=True, reverse=False)
|
||||
x = vel_inv[:,0]; y = vel_inv[:,1]; value = (vel_inv[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(grid = grid)
|
||||
# earthquakes
|
||||
fig.plot(x = re_loc[0,ev_idx1], y = re_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = re_loc[0,ev_idx2], y = re_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = re_loc[0,ev_idx3], y = re_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
# stations
|
||||
# fig.plot(x = loc_st[0,:], y = loc_st[1,:], style = "t0.4c", fill = "blue", pen = "black", label = "Station")
|
||||
|
||||
# anisotropic arrow
|
||||
fig.plot(ani_inv, style='j', fill='yellow1', pen='0.5p,black')
|
||||
|
||||
fig.shift_origin(xshift=11)
|
||||
|
||||
fig.basemap(region=[0,40,0,2], frame=["xa20+lDepth (km)","ya1","Nswe"], projection="X2c/10c")
|
||||
x = vel_inv_sec[:,3]; y = vel_inv_sec[:,1]; value = (vel_inv_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="1/0.04",region=[0,40,0,2])
|
||||
fig.grdimage(grid = grid)
|
||||
|
||||
# earthquakes
|
||||
fig.plot(x = re_loc[2,ev_idx1], y = re_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = re_loc[2,ev_idx2], y = re_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = re_loc[2,ev_idx3], y = re_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
# ------------------- colorbar -------------------
|
||||
fig.shift_origin(xshift=-11, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a%f"%(vel_range),"x+ldlnVp (%)"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.shift_origin(xshift=6, yshift=-1)
|
||||
fig.basemap(region=[0,1,0,1], frame=["wesn"], projection="X6c/1.5c")
|
||||
ani = [
|
||||
[0.2, 0.6, 45, 0.02*length, width], # lon, lat, phi, epsilon, size
|
||||
[0.5, 0.6, 45, 0.05*length, width],
|
||||
[0.8, 0.6, 45, 0.10*length, width],
|
||||
]
|
||||
fig.plot(ani, style='j', fill='yellow1', pen='0.5p,black')
|
||||
fig.text(text=["0.02", "0.05", "0.10"], x=[0.2,0.5,0.8], y=[0.2]*3, font="16p,Helvetica", justify="CM")
|
||||
fig.shift_origin(xshift= 11, yshift=2.5)
|
||||
|
||||
|
||||
fig.show()
|
||||
fig.savefig('img/model_%s.png'%(tag), dpi=300)
|
||||
|
||||
|
||||
61
examples/eg2_earthquake_location/prepare_input_files.py
Normal file
61
examples/eg2_earthquake_location/prepare_input_files.py
Normal file
@@ -0,0 +1,61 @@
|
||||
import numpy as np
|
||||
import os
|
||||
import sys
|
||||
try:
|
||||
from pytomoatt.checkerboard import Checker
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
from pytomoatt.model import ATTModel
|
||||
except:
|
||||
print("ERROR: ATTModel not found. Please install pytomoatt first."
|
||||
"See https://tomoatt.github.io/PyTomoATT/installation.html for details.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
class BuildInitialModel():
|
||||
def __init__(self, par_file="./3_input_params/input_params_signal.yaml", output_dir="2_models"):
|
||||
"""
|
||||
Build initial model for tomography inversion
|
||||
"""
|
||||
self.am = ATTModel(par_file)
|
||||
self.output_dir = output_dir
|
||||
|
||||
def build_initial_model(self, vel_min=5.0, vel_max=8.0):
|
||||
"""
|
||||
Build initial model for tomography inversion
|
||||
"""
|
||||
self.am.vel[self.am.depths < 0, :, :] = vel_min
|
||||
idx = np.where((0 <= self.am.depths) & (self.am.depths < 40.0))[0]
|
||||
self.am.vel[idx, :, :] = np.linspace(vel_min, vel_max, idx.size)[::-1][:, np.newaxis, np.newaxis]
|
||||
self.am.vel[self.am.depths >= 40.0, :, :] = vel_max
|
||||
|
||||
|
||||
def build_ckb_model(output_dir="2_models"):
|
||||
cbk = Checker(f'{output_dir}/model_init_N61_61_61.h5', para_fname="./3_input_params/input_params_signal.yaml")
|
||||
cbk.checkerboard(
|
||||
n_pert_x=2, n_pert_y=2, n_pert_z=2,
|
||||
pert_vel=0.2, pert_ani=0.1, ani_dir=60.0,
|
||||
lim_x=[0.5, 1.5], lim_y=[0.5, 1.5], lim_z=[0, 40]
|
||||
)
|
||||
cbk.write(f'{output_dir}/model_ckb_N61_61_61.h5')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# download src_rec_file
|
||||
url = 'https://zenodo.org/records/14053821/files/src_rec_config.dat'
|
||||
path = "1_src_rec_files/src_rec_config.dat"
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
if not os.path.exists(path):
|
||||
sr = SrcRec.read(url)
|
||||
sr.write(path)
|
||||
|
||||
# build initial model
|
||||
output_dir = "2_models"
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
bim = BuildInitialModel(output_dir=output_dir)
|
||||
bim.build_initial_model()
|
||||
bim.am.write('{}/model_init_N{:d}_{:d}_{:d}.h5'.format(bim.output_dir, *bim.am.n_rtp))
|
||||
|
||||
build_ckb_model(output_dir)
|
||||
|
||||
|
||||
27
examples/eg2_earthquake_location/run_this_example.sh
Normal file
27
examples/eg2_earthquake_location/run_this_example.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
# Step 1: Generate necessary input files
|
||||
python prepare_input_files.py
|
||||
|
||||
# Step 2: Run forward modeling
|
||||
# # for WSL
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_signal.yaml
|
||||
# # for Linux
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_signal.yaml
|
||||
# for conda install
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_signal.yaml
|
||||
|
||||
# Step 3: Assign data noise and location perturbation to the observational data
|
||||
python assign_gaussian_noise.py
|
||||
|
||||
# Step 4: Do relocation
|
||||
# # for WSL
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_loc.yaml
|
||||
# # for Linux
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_loc.yaml
|
||||
# for conda install
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_loc.yaml
|
||||
|
||||
# Step 5 (Optional): Plot the results
|
||||
# python plot_output.py
|
||||
@@ -0,0 +1,114 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-10, 50] # depth in km
|
||||
min_max_lat: [0, 2] # latitude in degree
|
||||
min_max_lon: [0, 2] # longitude in degree
|
||||
n_rtp: [61, 61, 61] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: OUTPUT_FILES/OUTPUT_FILES_signal/src_rec_file_forward_errloc.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_init_N61_61_61.h5 # path to initial model file
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_joint_step1 # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_final_model: true # output merged final model (final_model.h5) or not.
|
||||
output_in_process: false # output model at each inv iteration or not.
|
||||
output_in_process_data: false # output src_rec_file at each inv iteration or not.
|
||||
output_file_format: 0
|
||||
|
||||
# output files:
|
||||
# File: 'out_data_grid.h5'. Keys: ['Mesh']['elem_conn'], element index;
|
||||
# ['Mesh']['node_coords_p'], phi coordinates of nodes;
|
||||
# ['Mesh']['node_coords_t'], theta coordinates of nodes;
|
||||
# ['Mesh']['node_coords_r'], r coordinates of nodes;
|
||||
# ['Mesh']['node_coords_x'], phi coordinates of elements;
|
||||
# ['Mesh']['node_coords_y'], theta coordinates of elements;
|
||||
# ['Mesh']['node_coords_z'], r coordinates of elements;
|
||||
# File: 'out_data_sim_group_0'. Keys: ['model']['vel_inv_XXXX'], velocity model at iteration XXXX;
|
||||
# ['model']['xi_inv_XXXX'], xi model at iteration XXXX;
|
||||
# ['model']['eta_inv_XXXX'], eta model at iteration XXXX
|
||||
# ['model']['Ks_inv_XXXX'], sensitivity kernel related to slowness at iteration XXXX
|
||||
# ['model']['Kxi_inv_XXXX'], sensitivity kernel related to xi at iteration XXXX
|
||||
# ['model']['Keta_inv_XXXX'], sensitivity kernel related to eta at iteration XXXX
|
||||
# ['model']['Ks_density_inv_XXXX'], kernel density of Ks at iteration XXXX
|
||||
# ['model']['Kxi_density_inv_XXXX'], kernel density of Kxi at iteration XXXX
|
||||
# ['model']['Keta_density_inv_XXXX'], kernel density of Keta at iteration XXXX
|
||||
# ['model']['Ks_over_Kden_inv_XXXX'], slowness kernel over kernel density at iteration XXXX
|
||||
# ['model']['Kxi_over_Kden_inv_XXXX'], xi kernel over kernel density at iteration XXXX
|
||||
# ['model']['Keta_over_Kden_inv_XXXX'], eta kernel over kernel density at iteration XXXX
|
||||
# ['model']['Ks_update_inv_XXXX'], slowness kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Kxi_update_inv_XXXX'], xi kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Keta_update_inv_XXXX'], eta kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['1dinv']['vel_1dinv_inv_XXXX'], 2d velocity model at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['r_1dinv'], r coordinates (depth), in 1d inversion mode
|
||||
# ['1dinv']['t_1dinv'], t coordinates (epicenter distance), in 1d inversion mode
|
||||
# File: 'src_rec_file_step_XXXX.dat' or 'src_rec_file_forward.dat'. The synthetic traveltime data file.
|
||||
# File: 'final_model.h5'. Keys: ['eta'], ['xi'], ['vel'], the final model.
|
||||
# File: 'middle_model_step_XXXX.h5'. Keys: ['eta'], ['xi'], ['vel'], the model at step XXXX.
|
||||
# File: 'inversion_grid.txt'. The location of inversion grid nodes
|
||||
# File: 'objective_function.txt'. The objective function value at each iteration
|
||||
# File: 'out_data_sim_group_X'. Keys: ['src_YYYY']['time_field_inv_XXXX'], traveltime field of source YYYY at iteration XXXX;
|
||||
# ['src_YYYY']['adjoint_field_inv_XXXX'], adjoint field of source YYYY at iteration XXXX;
|
||||
# ['1dinv']['time_field_1dinv_YYYY_inv_XXXX'], 2d traveltime field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['adjoint_field_1dinv_YYYY_inv_XXXX'], 2d adjoint field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
# 4 for 1d model inversion
|
||||
run_mode: 2
|
||||
|
||||
#################################################
|
||||
# relocation parameters setting #
|
||||
#################################################
|
||||
relocation: # update earthquake hypocenter and origin time (when run_mode : 2 and 3)
|
||||
min_Ndata: 4 # if the number of data of the earthquake is less than <min_Ndata>, the earthquake will not be relocated. defaut value: 4
|
||||
|
||||
# relocation_strategy
|
||||
step_length : 0.01 # initial step length of relocation perturbation. 0.01 means maximum 1% perturbation for each iteration.
|
||||
step_length_decay : 0.9 # if objective function increase, step size -> step length * step_length_decay. default: 0.9
|
||||
rescaling_dep_lat_lon_ortime: [10.0, 15.0, 15.0, 1.0] # The perturbation is related to <rescaling_dep_lat_lon_ortime>. Unit: km,km,km,second
|
||||
max_change_dep_lat_lon_ortime: [10.0, 15.0, 15.0, 1.0] # the change of dep,lat,lon,ortime do not exceed max_change. Unit: km,km,km,second
|
||||
max_iterations : 50 # maximum number of iterations for relocation
|
||||
tol_gradient : 0.0001 # if the norm of gradient is smaller than the tolerance, the iteration of relocation terminates
|
||||
|
||||
# -------------- using absolute traveltime data --------------
|
||||
abs_time:
|
||||
use_abs_time : true # 'yes' for using absolute traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- using common source differential traveltime data --------------
|
||||
cs_dif_time:
|
||||
use_cs_time : false # 'yes' for using common source differential traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- using common receiver differential traveltime data --------------
|
||||
cr_dif_time:
|
||||
use_cr_time : true # 'yes' for using common receiver differential traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
@@ -0,0 +1,312 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-10, 50] # depth in km
|
||||
min_max_lat: [0, 2] # latitude in degree
|
||||
min_max_lon: [0, 2] # longitude in degree
|
||||
n_rtp: [61, 61, 61] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: OUTPUT_FILES/OUTPUT_FILES_joint_step1/src_rec_file_reloc_0050_obs.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver (only valid for regional source and receiver, those of tele remain unchanged)
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_init_N61_61_61.h5 # path to initial model file
|
||||
# model_1d_name: dummy_model_1d_name # 1D model name used in teleseismic 2D solver (iasp91, ak135, user_defined is available), defined in include/1d_model.h
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
nproc_sub: 1 # number of processors for sweep parallelization (parallel the fast sweep method)
|
||||
use_gpu: false # true if use gpu (EXPERIMENTAL)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_joint_step2 # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_source_field: false # True: output the traveltime field and adjoint field of all sources at each iteration. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_kernel: false # True: output sensitivity kernel and kernel density. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_final_model: true # True: output merged final model. This file can be used as the input model for TomoATT. Default: true. File: 'model_final.h5'.
|
||||
output_middle_model: false # True: output merged intermediate models during inversion. This file can be used as the input model for TomoATT. Default: false. File: 'middle_model_step_XXXX.h5'
|
||||
output_in_process: false # True: output at each inv iteration, otherwise, only output step 0, Niter-1, Niter. Default: true. File: 'out_data_sim_group_0'.
|
||||
output_in_process_data: false # True: output src_rec_file at each inv iteration, otherwise, only output step 0, Niter-2, Niter-1. Default: true. File: 'src_rec_file_step_XXXX.dat'
|
||||
single_precision_output: false # True: output results in single precision. Default: false.
|
||||
verbose_output_level: 0 # output internal parameters, (to do).
|
||||
output_file_format: 0 # 0: hdf5, 1: ascii
|
||||
|
||||
# output files:
|
||||
# File: 'out_data_grid.h5'. Keys: ['Mesh']['elem_conn'], element index;
|
||||
# ['Mesh']['node_coords_p'], phi coordinates of nodes;
|
||||
# ['Mesh']['node_coords_t'], theta coordinates of nodes;
|
||||
# ['Mesh']['node_coords_r'], r coordinates of nodes;
|
||||
# ['Mesh']['node_coords_x'], phi coordinates of elements;
|
||||
# ['Mesh']['node_coords_y'], theta coordinates of elements;
|
||||
# ['Mesh']['node_coords_z'], r coordinates of elements;
|
||||
# File: 'out_data_sim_group_0'. Keys: ['model']['vel_inv_XXXX'], velocity model at iteration XXXX;
|
||||
# ['model']['xi_inv_XXXX'], xi model at iteration XXXX;
|
||||
# ['model']['eta_inv_XXXX'], eta model at iteration XXXX
|
||||
# ['model']['Ks_inv_XXXX'], sensitivity kernel related to slowness at iteration XXXX
|
||||
# ['model']['Kxi_inv_XXXX'], sensitivity kernel related to xi at iteration XXXX
|
||||
# ['model']['Keta_inv_XXXX'], sensitivity kernel related to eta at iteration XXXX
|
||||
# ['model']['Ks_density_inv_XXXX'], kernel density of Ks at iteration XXXX
|
||||
# ['model']['Kxi_density_inv_XXXX'], kernel density of Kxi at iteration XXXX
|
||||
# ['model']['Keta_density_inv_XXXX'], kernel density of Keta at iteration XXXX
|
||||
# ['model']['Ks_over_Kden_inv_XXXX'], slowness kernel over kernel density at iteration XXXX
|
||||
# ['model']['Kxi_over_Kden_inv_XXXX'], xi kernel over kernel density at iteration XXXX
|
||||
# ['model']['Keta_over_Kden_inv_XXXX'], eta kernel over kernel density at iteration XXXX
|
||||
# ['model']['Ks_update_inv_XXXX'], slowness kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Kxi_update_inv_XXXX'], xi kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Keta_update_inv_XXXX'], eta kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['1dinv']['vel_1dinv_inv_XXXX'], 2d velocity model at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['r_1dinv'], r coordinates (depth), in 1d inversion mode
|
||||
# ['1dinv']['t_1dinv'], t coordinates (epicenter distance), in 1d inversion mode
|
||||
# File: 'src_rec_file_step_XXXX.dat' or 'src_rec_file_forward.dat'. The synthetic traveltime data file.
|
||||
# File: 'final_model.h5'. Keys: ['eta'], ['xi'], ['vel'], the final model.
|
||||
# File: 'middle_model_step_XXXX.h5'. Keys: ['eta'], ['xi'], ['vel'], the model at step XXXX.
|
||||
# File: 'inversion_grid.txt'. The location of inversion grid nodes
|
||||
# File: 'objective_function.txt'. The objective function value at each iteration
|
||||
# File: 'out_data_sim_group_X'. Keys: ['src_YYYY']['time_field_inv_XXXX'], traveltime field of source YYYY at iteration XXXX;
|
||||
# ['src_YYYY']['adjoint_field_inv_XXXX'], adjoint field of source YYYY at iteration XXXX;
|
||||
# ['1dinv']['time_field_1dinv_YYYY_inv_XXXX'], 2d traveltime field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['adjoint_field_1dinv_YYYY_inv_XXXX'], 2d adjoint field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
# 4 for 1d model inversion
|
||||
run_mode: 3
|
||||
|
||||
have_tele_data: false # An error will be reported if false but source out of study region is used. Default: false.
|
||||
|
||||
|
||||
###################################################
|
||||
# model update parameters setting #
|
||||
###################################################
|
||||
model_update:
|
||||
max_iterations: 40 # maximum number of inversion iterations
|
||||
optim_method: 0 # optimization method. 0 : grad_descent, 1 : halve-stepping, 2 : lbfgs (EXPERIMENTAL)
|
||||
|
||||
#common parameters for all optim methods
|
||||
step_length: 0.02 # the initial step length of model perturbation. 0.01 means maximum 1% perturbation for each iteration.
|
||||
|
||||
# parameters for optim_method 0 (gradient_descent)
|
||||
optim_method_0:
|
||||
step_method: 1 # the method to modulate step size. 0: according to objective function; 1: according to gradient direction
|
||||
# if step_method:0. if objective function increase, step size -> step length * step_length_decay.
|
||||
step_length_decay: 0.9 # default: 0.9
|
||||
# if step_method:1. if the angle between the current and the previous gradients is greater than step_length_gradient_angle, step size -> step length * step_length_change[0].
|
||||
# otherwise, step size -> step length * step_length_change[1].
|
||||
step_length_gradient_angle: 120 # default: 120.0
|
||||
step_length_change: [0.5, 1.2] # default: [0.5,1.2]
|
||||
# Kdensity_coe is used to rescale the final kernel: kernel -> kernel / pow(density of kernel, Kdensity_coe). if Kdensity_coe > 0, the region with less data will be enhanced during the inversion
|
||||
# e.g., if Kdensity_coe = 0, kernel remains upchanged; if Kdensity_coe = 1, kernel is fully normalized. 0.5 or less is recommended if really required.
|
||||
Kdensity_coe: 0 # default: 0.0, limited range: 0.0 - 0.95
|
||||
|
||||
# parameters for optim_method 1 (halve-stepping) or 2 (lbfgs)
|
||||
optim_method_1_2:
|
||||
max_sub_iterations: 20 # maximum number of each sub-iteration
|
||||
regularization_weight: 0.5 # weight value for regularization (lbfgs mode only)
|
||||
coefs_regulalization_rtp: [1, 1, 1] # regularization coefficients for rtp (lbfgs mode only)
|
||||
|
||||
# smoothing
|
||||
smoothing:
|
||||
smooth_method: 0 # 0: multiparametrization, 1: laplacian smoothing (EXPERIMENTAL)
|
||||
l_smooth_rtp: [1, 1, 1] # smoothing coefficients for laplacian smoothing
|
||||
|
||||
# parameters for smooth method 0 (multigrid model parametrization)
|
||||
# inversion grid can be viewed in OUTPUT_FILES/inversion_grid.txt
|
||||
n_inversion_grid: 5 # number of inversion grid sets
|
||||
|
||||
uniform_inv_grid_dep: false # true if use uniform inversion grid for dep, false if use flexible inversion grid
|
||||
uniform_inv_grid_lat: true # true if use uniform inversion grid for lat, false if use flexible inversion grid
|
||||
uniform_inv_grid_lon: true # true if use uniform inversion grid for lon, false if use flexible inversion grid
|
||||
|
||||
# -------------- uniform inversion grid setting --------------
|
||||
# settings for uniform inversion grid
|
||||
n_inv_dep_lat_lon: [12, 9, 9] # number of the base inversion grid points
|
||||
min_max_dep_inv: [-10, 50] # depth in km (Radius of the earth is defined in config.h/R_earth)
|
||||
min_max_lat_inv: [0, 2] # latitude in degree
|
||||
min_max_lon_inv: [0, 2] # longitude in degree
|
||||
|
||||
# -------------- flexible inversion grid setting --------------
|
||||
# settings for flexible inversion grid
|
||||
dep_inv: [-10, 0, 10, 20, 30, 40, 50, 60] # inversion grid for vel in depth (km)
|
||||
lat_inv: [30, 30.2, 30.4, 30.6, 30.8, 31, 31.2, 31.4, 31.6, 31.8, 32] # inversion grid for vel in latitude (degree)
|
||||
lon_inv: [30, 30.2, 30.4, 30.6, 30.8, 31, 31.2, 31.4, 31.6, 31.8, 32] # inversion grid for vel in longitude (degree)
|
||||
trapezoid: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
|
||||
|
||||
# if we want to use another inversion grid for inverting anisotropy, set invgrid_ani: true (default: false)
|
||||
invgrid_ani: false
|
||||
|
||||
# ---------- uniform inversion grid setting for anisotropy ----------
|
||||
n_inv_dep_lat_lon_ani: [12, 11, 11] # number of the base inversion grid points
|
||||
min_max_dep_inv_ani: [-7, 63] # depth in km (Radius of the earth is defined in config.h/R_earth)
|
||||
min_max_lat_inv_ani: [30, 32] # latitude in degree
|
||||
min_max_lon_inv_ani: [30, 32] # longitude in degree
|
||||
|
||||
# ---------- flexible inversion grid setting for anisotropy ----------
|
||||
# settings for flexible inversion grid for anisotropy
|
||||
dep_inv_ani: [-7, -3, 0, 3, 7, 12, 18, 25, 33, 42, 52, 63] # inversion grid for ani in depth (km)
|
||||
lat_inv_ani: [30, 30.2, 30.4, 30.6, 30.8, 31, 31.2, 31.4, 31.6, 31.8, 32] # inversion grid for ani in latitude (degree)
|
||||
lon_inv_ani: [30, 30.2, 30.4, 30.6, 30.8, 31, 31.2, 31.4, 31.6, 31.8, 32] # inversion grid for ani in longitude (degree)
|
||||
trapezoid_ani: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
|
||||
|
||||
# Carefully change trapezoid and trapezoid_ani, if you really want to use trapezoid inversion grid, increasing the inversion grid spacing with depth to account for the worse data coverage in greater depths.
|
||||
# The trapezoid_ inversion grid with index (i,j,k) in longitude, latitude, and depth is defined as:
|
||||
# if dep_inv[k] < trapezoid[1], lon = lon_inv[i];
|
||||
# lat = lat_inv[j];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[1] <= dep_inv[k] < trapezoid[2], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[2] <= dep_inv[k], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# The shape of trapezoid inversion gird (x) looks like:
|
||||
#
|
||||
# lon_inv[0] [1] [2] [3] [4]
|
||||
# |<-------- (lon_inv[end] - lon_inv[0]) ---->|
|
||||
# dep_inv[0] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[1] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[2] = trapezoid[1] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[3] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[4] = trapezoid[2] / x x x x x \
|
||||
# | |
|
||||
# dep_inv[5] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[6] | x x x x x |
|
||||
# |<---- trapezoid[0]* (lon_inv[end] - lon_inv[0]) ------>|
|
||||
|
||||
# inversion grid volume rescale (kernel -> kernel / volume of inversion grid mesh),
|
||||
# this precondition may be carefully applied if the sizes of inversion grids are unbalanced
|
||||
invgrid_volume_rescale: false
|
||||
|
||||
# path to station correction file (under development)
|
||||
use_sta_correction: false
|
||||
# initial_sta_correction_file: dummy_sta_correction_file # the path of initial station correction
|
||||
step_length_sta_correction: 0.001 # step length relate to the update of station correction terms
|
||||
|
||||
|
||||
# In the following data subsection, XXX_weight means a weight is assigned to the data, influencing the objective function and gradient
|
||||
# XXX_weight : [d1,d2,w1,w2] means:
|
||||
# if XXX < d1, weight = w1
|
||||
# if d1 <= XXX < d2, weight = w1 + (XXX-d1)/(d2-d1)*(w2-w1), (linear interpolation)
|
||||
# if d2 <= XXX , weight = w2
|
||||
# You can easily set w1 = w2 = 1.0 to normalize the weight related to XXX.
|
||||
# -------------- using absolute traveltime data --------------
|
||||
abs_time:
|
||||
use_abs_time: true # 'true' for using absolute traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the absolute traveltime residual (second) = abs(t^{obs}_{n,i} - t^{syn}_{n,j})
|
||||
distance_weight: [100, 200, 1, 1] # XXX is epicenter distance (km) between the source and receiver related to the data
|
||||
|
||||
# -------------- using common source differential traveltime data --------------
|
||||
cs_dif_time:
|
||||
use_cs_time: true # 'true' for using common source differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the common source differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{n,j} - t^{syn}_{n,i} + t^{syn}_{n,j}).
|
||||
azimuthal_weight: [15, 30, 1, 1] # XXX is the azimuth difference between two separate stations related to the common source.
|
||||
|
||||
# -------------- using common receiver differential traveltime data --------------
|
||||
cr_dif_time:
|
||||
use_cr_time: false # 'true' for using common receiver differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the common receiver differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{m,i} - t^{syn}_{n,i} + t^{syn}_{m,i})
|
||||
azimuthal_weight: [15, 30, 1, 1] # XXX is the azimuth difference between two separate sources related to the common receiver.
|
||||
|
||||
# -------------- global weight of different types of data (to balance the weight of different data) --------------
|
||||
global_weight:
|
||||
balance_data_weight: true # yes: over the total weight of the each type of the data. no: use original weight (below weight for each type of data needs to be set)
|
||||
abs_time_weight: 1 # weight of absolute traveltime data after balance, default: 1.0
|
||||
cs_dif_time_local_weight: 1 # weight of common source differential traveltime data after balance, default: 1.0
|
||||
cr_dif_time_local_weight: 1 # weight of common receiver differential traveltime data after balance, default: 1.0
|
||||
teleseismic_weight: 1 # weight of teleseismic data after balance, default: 1.0 (exclude in this version)
|
||||
|
||||
# -------------- inversion parameters --------------
|
||||
update_slowness : true # update slowness (velocity) or not. default: true
|
||||
update_azi_ani : true # update azimuthal anisotropy (xi, eta) or not. default: false
|
||||
|
||||
# -------------- for teleseismic inversion (under development) --------------
|
||||
# depth_taper : [d1,d2] means:
|
||||
# if XXX < d1, kernel <- kernel * 0.0
|
||||
# if d1 <= XXX < d2, kernel <- kernel * (XXX-d1)/(d2-d1), (linear interpolation)
|
||||
# if d2 <= XXX , kernel <- kernel * 1.0
|
||||
# You can easily set d1 = -200, d1 = -100 to remove this taper.
|
||||
depth_taper : [-1e+07, -1e+07]
|
||||
|
||||
#################################################
|
||||
# relocation parameters setting #
|
||||
#################################################
|
||||
relocation: # update earthquake hypocenter and origin time (when run_mode : 2 and 3)
|
||||
min_Ndata: 4 # if the number of data of the earthquake is less than <min_Ndata>, the earthquake will not be relocated. defaut value: 4
|
||||
|
||||
# relocation_strategy
|
||||
step_length : 0.01 # initial step length of relocation perturbation. 0.01 means maximum 1% perturbation for each iteration.
|
||||
step_length_decay : 0.9 # if objective function increase, step size -> step length * step_length_decay. default: 0.9
|
||||
rescaling_dep_lat_lon_ortime : [10, 15, 15, 1] # The perturbation is related to <rescaling_dep_lat_lon_ortime>. Unit: km,km,km,second
|
||||
max_change_dep_lat_lon_ortime : [10, 15, 15, 1] # the change of dep,lat,lon,ortime do not exceed max_change. Unit: km,km,km,second
|
||||
max_iterations : 201 # maximum number of iterations for relocation
|
||||
tol_gradient : 0.0001 # if the norm of gradient is smaller than the tolerance, the iteration of relocation terminates
|
||||
|
||||
# -------------- using absolute traveltime data --------------
|
||||
abs_time:
|
||||
use_abs_time : true # 'yes' for using absolute traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
residual_weight : [1, 3, 1, 1] # XXX is the absolute traveltime residual (second) = abs(t^{obs}_{n,i} - t^{syn}_{n,j})
|
||||
distance_weight : [1, 3, 1, 1] # XXX is epicenter distance (km) between the source and receiver related to the data
|
||||
|
||||
# -------------- using common source differential traveltime data --------------
|
||||
cs_dif_time:
|
||||
use_cs_time : false # 'yes' for using common source differential traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
residual_weight : [1, 3, 1, 1] # XXX is the common source differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{n,j} - t^{syn}_{n,i} + t^{syn}_{n,j}).
|
||||
azimuthal_weight : [100, 200, 1, 1] # XXX is the azimuth difference between two separate stations related to the common source.
|
||||
|
||||
# -------------- using common receiver differential traveltime data --------------
|
||||
cr_dif_time:
|
||||
use_cr_time : true # 'yes' for using common receiver differential traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
residual_weight : [15, 30, 1, 1] # XXX is the common receiver differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{m,i} - t^{syn}_{n,i} + t^{syn}_{m,i})
|
||||
azimuthal_weight : [15, 30, 1, 1] # XXX is the azimuth difference between two separate sources related to the common receiver.
|
||||
|
||||
|
||||
# -------------- global weight of different types of data (to balance the weight of different data) --------------
|
||||
global_weight:
|
||||
balance_data_weight: true # yes: over the total weight of the each type of the data. no: use original weight (below weight for each type of data needs to be set)
|
||||
abs_time_local_weight: 1 # weight of absolute traveltime data for relocation after balance, default: 1.0
|
||||
cs_dif_time_local_weight: 1 # weight of common source differential traveltime data for relocation after balance, default: 1.0
|
||||
cr_dif_time_local_weight: 1 # weight of common receiver differential traveltime data for relocation after balance, default: 1.0
|
||||
|
||||
####################################################################
|
||||
# inversion strategy for tomography and relocation #
|
||||
####################################################################
|
||||
inversion_strategy: # update model parameters and earthquake hypocenter iteratively (when run_mode : 3)
|
||||
|
||||
inv_mode : 1 # 0 for update model parameters and relocation iteratively. 1 for update model parameters and relocation simultaneously.
|
||||
|
||||
# for inv_mode : 0, parameters below are required
|
||||
inv_mode_0: # update model for <model_update_N_iter> steps, then update location for <relocation_N_iter> steps, and repeat the process for <max_loop> loops.
|
||||
model_update_N_iter : 1
|
||||
relocation_N_iter : 1
|
||||
max_loop : 10
|
||||
|
||||
# for inv_mode : 1, parameters below are required
|
||||
inv_mode_1: # update model and location simultaneously for <max_loop> loops.
|
||||
max_loop : 40
|
||||
@@ -0,0 +1,139 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-10, 50] # depth in km
|
||||
min_max_lat: [0, 2] # latitude in degree
|
||||
min_max_lon: [0, 2] # longitude in degree
|
||||
n_rtp: [61, 61, 61] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: OUTPUT_FILES/OUTPUT_FILES_joint_step2/src_rec_file_inv_0039_reloc_0039_obs.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver (only valid for regional source and receiver, those of tele remain unchanged)
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: OUTPUT_FILES/OUTPUT_FILES_joint_step2/final_model.h5 # path to initial model file
|
||||
# model_1d_name: dummy_model_1d_name # 1D model name used in teleseismic 2D solver (iasp91, ak135, user_defined is available), defined in include/1d_model.h
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
nproc_sub: 1 # number of processors for sweep parallelization (parallel the fast sweep method)
|
||||
use_gpu: false # true if use gpu (EXPERIMENTAL)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_joint_step3 # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_source_field: false # True: output the traveltime field and adjoint field of all sources at each iteration. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_kernel: false # True: output sensitivity kernel and kernel density. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_final_model: true # True: output merged final model. This file can be used as the input model for TomoATT. Default: true. File: 'model_final.h5'.
|
||||
output_middle_model: false # True: output merged intermediate models during inversion. This file can be used as the input model for TomoATT. Default: false. File: 'middle_model_step_XXXX.h5'
|
||||
output_in_process: false # True: output at each inv iteration, otherwise, only output step 0, Niter-1, Niter. Default: true. File: 'out_data_sim_group_0'.
|
||||
output_in_process_data: false # True: output src_rec_file at each inv iteration, otherwise, only output step 0, Niter-2, Niter-1. Default: true. File: 'src_rec_file_step_XXXX.dat'
|
||||
single_precision_output: false # True: output results in single precision. Default: false.
|
||||
verbose_output_level: 0 # output internal parameters, (to do).
|
||||
output_file_format: 0 # 0: hdf5, 1: ascii
|
||||
|
||||
# output files:
|
||||
# File: 'out_data_grid.h5'. Keys: ['Mesh']['elem_conn'], element index;
|
||||
# ['Mesh']['node_coords_p'], phi coordinates of nodes;
|
||||
# ['Mesh']['node_coords_t'], theta coordinates of nodes;
|
||||
# ['Mesh']['node_coords_r'], r coordinates of nodes;
|
||||
# ['Mesh']['node_coords_x'], phi coordinates of elements;
|
||||
# ['Mesh']['node_coords_y'], theta coordinates of elements;
|
||||
# ['Mesh']['node_coords_z'], r coordinates of elements;
|
||||
# File: 'out_data_sim_group_0'. Keys: ['model']['vel_inv_XXXX'], velocity model at iteration XXXX;
|
||||
# ['model']['xi_inv_XXXX'], xi model at iteration XXXX;
|
||||
# ['model']['eta_inv_XXXX'], eta model at iteration XXXX
|
||||
# ['model']['Ks_inv_XXXX'], sensitivity kernel related to slowness at iteration XXXX
|
||||
# ['model']['Kxi_inv_XXXX'], sensitivity kernel related to xi at iteration XXXX
|
||||
# ['model']['Keta_inv_XXXX'], sensitivity kernel related to eta at iteration XXXX
|
||||
# ['model']['Ks_density_inv_XXXX'], kernel density of Ks at iteration XXXX
|
||||
# ['model']['Kxi_density_inv_XXXX'], kernel density of Kxi at iteration XXXX
|
||||
# ['model']['Keta_density_inv_XXXX'], kernel density of Keta at iteration XXXX
|
||||
# ['model']['Ks_over_Kden_inv_XXXX'], slowness kernel over kernel density at iteration XXXX
|
||||
# ['model']['Kxi_over_Kden_inv_XXXX'], xi kernel over kernel density at iteration XXXX
|
||||
# ['model']['Keta_over_Kden_inv_XXXX'], eta kernel over kernel density at iteration XXXX
|
||||
# ['model']['Ks_update_inv_XXXX'], slowness kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Kxi_update_inv_XXXX'], xi kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Keta_update_inv_XXXX'], eta kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['1dinv']['vel_1dinv_inv_XXXX'], 2d velocity model at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['r_1dinv'], r coordinates (depth), in 1d inversion mode
|
||||
# ['1dinv']['t_1dinv'], t coordinates (epicenter distance), in 1d inversion mode
|
||||
# File: 'src_rec_file_step_XXXX.dat' or 'src_rec_file_forward.dat'. The synthetic traveltime data file.
|
||||
# File: 'final_model.h5'. Keys: ['eta'], ['xi'], ['vel'], the final model.
|
||||
# File: 'middle_model_step_XXXX.h5'. Keys: ['eta'], ['xi'], ['vel'], the model at step XXXX.
|
||||
# File: 'inversion_grid.txt'. The location of inversion grid nodes
|
||||
# File: 'objective_function.txt'. The objective function value at each iteration
|
||||
# File: 'out_data_sim_group_X'. Keys: ['src_YYYY']['time_field_inv_XXXX'], traveltime field of source YYYY at iteration XXXX;
|
||||
# ['src_YYYY']['adjoint_field_inv_XXXX'], adjoint field of source YYYY at iteration XXXX;
|
||||
# ['1dinv']['time_field_1dinv_YYYY_inv_XXXX'], 2d traveltime field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['adjoint_field_1dinv_YYYY_inv_XXXX'], 2d adjoint field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
# 4 for 1d model inversion
|
||||
run_mode: 2
|
||||
|
||||
have_tele_data: false # An error will be reported if false but source out of study region is used. Default: false.
|
||||
|
||||
|
||||
#################################################
|
||||
# relocation parameters setting #
|
||||
#################################################
|
||||
relocation: # update earthquake hypocenter and origin time (when run_mode : 2 and 3)
|
||||
min_Ndata: 4 # if the number of data of the earthquake is less than <min_Ndata>, the earthquake will not be relocated. defaut value: 4
|
||||
|
||||
# relocation_strategy
|
||||
step_length : 0.01 # initial step length of relocation perturbation. 0.01 means maximum 1% perturbation for each iteration.
|
||||
step_length_decay : 0.9 # if objective function increase, step size -> step length * step_length_decay. default: 0.9
|
||||
rescaling_dep_lat_lon_ortime : [10, 15, 15, 1] # The perturbation is related to <rescaling_dep_lat_lon_ortime>. Unit: km,km,km,second
|
||||
max_change_dep_lat_lon_ortime : [10, 15, 15, 1] # the change of dep,lat,lon,ortime do not exceed max_change. Unit: km,km,km,second
|
||||
max_iterations : 100 # maximum number of iterations for relocation
|
||||
tol_gradient : 0.0001 # if the norm of gradient is smaller than the tolerance, the iteration of relocation terminates
|
||||
|
||||
# -------------- using absolute traveltime data --------------
|
||||
abs_time:
|
||||
use_abs_time : false # 'yes' for using absolute traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
residual_weight : [1, 3, 1, 1] # XXX is the absolute traveltime residual (second) = abs(t^{obs}_{n,i} - t^{syn}_{n,j})
|
||||
distance_weight : [1, 3, 1, 1] # XXX is epicenter distance (km) between the source and receiver related to the data
|
||||
|
||||
# -------------- using common source differential traveltime data --------------
|
||||
cs_dif_time:
|
||||
use_cs_time : false # 'yes' for using common source differential traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
residual_weight : [1, 3, 1, 1] # XXX is the common source differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{n,j} - t^{syn}_{n,i} + t^{syn}_{n,j}).
|
||||
azimuthal_weight : [100, 200, 1, 1] # XXX is the azimuth difference between two separate stations related to the common source.
|
||||
|
||||
# -------------- using common receiver differential traveltime data --------------
|
||||
cr_dif_time:
|
||||
use_cr_time : true # 'yes' for using common receiver differential traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
|
||||
residual_weight : [15, 30, 1, 1] # XXX is the common receiver differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{m,i} - t^{syn}_{n,i} + t^{syn}_{m,i})
|
||||
azimuthal_weight : [15, 30, 1, 1] # XXX is the azimuth difference between two separate sources related to the common receiver.
|
||||
|
||||
|
||||
# -------------- global weight of different types of data (to balance the weight of different data) --------------
|
||||
global_weight:
|
||||
balance_data_weight: true # yes: over the total weight of the each type of the data. no: use original weight (below weight for each type of data needs to be set)
|
||||
abs_time_local_weight: 1 # weight of absolute traveltime data for relocation after balance, default: 1.0
|
||||
cs_dif_time_local_weight: 1 # weight of common source differential traveltime data for relocation after balance, default: 1.0
|
||||
cr_dif_time_local_weight: 1 # weight of common receiver differential traveltime data for relocation after balance, default: 1.0
|
||||
@@ -0,0 +1,50 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-10, 50] # depth in km
|
||||
min_max_lat: [0, 2] # latitude in degree
|
||||
min_max_lon: [0, 2] # longitude in degree
|
||||
n_rtp: [61, 61, 61] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: 1_src_rec_files/src_rec_config.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_ckb_N61_61_61.h5 # path to initial model file
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_signal # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_final_model: true # output merged final model (final_model.h5) or not.
|
||||
output_in_process: false # output model at each inv iteration or not.
|
||||
output_in_process_data: false # output src_rec_file at each inv iteration or not.
|
||||
output_file_format: 0
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
run_mode: 0
|
||||
29
examples/eg3_joint_inversion/README.md
Normal file
29
examples/eg3_joint_inversion/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# joint inversion
|
||||
|
||||
This is a toy model to simultaneously update model parameters and locate earthquakes (Figure 8e.)
|
||||
|
||||
Reference:
|
||||
[1] J. Chen, M. Nagaso, M. Xu, and P. Tong, TomoATT: An open-source package for Eikonal equation-based adjoint-state traveltime tomography for seismic velocity and azimuthal anisotropy, submitted.
|
||||
https://doi.org/10.48550/arXiv.2412.00031
|
||||
|
||||
Python modules are required to initiate the inversion and to plot final results:
|
||||
- h5py
|
||||
- PyTomoAT
|
||||
- Pygmt
|
||||
- gmt
|
||||
|
||||
Run this example:
|
||||
|
||||
1. Run bash script `bash run_this_example.sh` to execute the test.
|
||||
|
||||
2. After inversion, run `plot_output.py` to plot the results.
|
||||
|
||||
The initial and true models:
|
||||
|
||||

|
||||
|
||||
The inversion results:
|
||||
|
||||

|
||||
|
||||
|
||||
34
examples/eg3_joint_inversion/assign_gaussian_noise.py
Normal file
34
examples/eg3_joint_inversion/assign_gaussian_noise.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
|
||||
class AssignNoise:
|
||||
def __init__(self, in_fname, out_fname):
|
||||
self.in_fname = in_fname
|
||||
self.out_fname = out_fname
|
||||
self.sr = SrcRec.read(self.in_fname)
|
||||
|
||||
def assign_noise_for_tt(self, noise_level=0.1):
|
||||
self.sr.add_noise(noise_level)
|
||||
|
||||
def assign_noise_for_src(self, lat_pert=0.1, lon_pert=0.1, dep_pert=10, tau_pert=0.5):
|
||||
self.sr.add_noise_to_source(lat_pert, lon_pert, dep_pert, tau_pert)
|
||||
|
||||
if __name__ == "__main__":
|
||||
in_fname = "OUTPUT_FILES/OUTPUT_FILES_signal/src_rec_file_forward.dat" # input source receiver file
|
||||
out_fname = "OUTPUT_FILES/OUTPUT_FILES_signal/src_rec_file_forward_errloc.dat" # output source receiver file
|
||||
sigma = 0.1 # noise level in seconds
|
||||
lat_pert = 0.1 # assign noise for latitude in degrees
|
||||
lon_pert = 0.1 # assign noise for longitude in degrees
|
||||
dep_pert = 10 # assign noise for depth in km
|
||||
tau_pert = 0.5 # assign noise for origin time in seconds
|
||||
|
||||
# Initialize the instance
|
||||
an = AssignNoise(in_fname, out_fname)
|
||||
|
||||
# Assign noise for travel time
|
||||
an.assign_noise_for_tt(sigma)
|
||||
|
||||
# Assign noise for source
|
||||
an.assign_noise_for_src(lat_pert, lon_pert, dep_pert, tau_pert)
|
||||
|
||||
# Write the output file
|
||||
an.sr.write(out_fname)
|
||||
286
examples/eg3_joint_inversion/plot_output.py
Normal file
286
examples/eg3_joint_inversion/plot_output.py
Normal file
@@ -0,0 +1,286 @@
|
||||
# %%
|
||||
import pygmt
|
||||
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
|
||||
|
||||
import os
|
||||
|
||||
# %%
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.data import ATTData
|
||||
import numpy as np
|
||||
|
||||
# %%
|
||||
# read models
|
||||
|
||||
Ngrid = [61,61,61]
|
||||
data_file = '2_models/model_init_N%d_%d_%d.h5'%(Ngrid[0],Ngrid[1],Ngrid[2])
|
||||
par_file = '3_input_params/input_params_signal.yaml'
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
initial_model = model.to_xarray()
|
||||
|
||||
data_file = '2_models/model_ckb_N%d_%d_%d.h5'%(Ngrid[0],Ngrid[1],Ngrid[2])
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
ckb_model = model.to_xarray()
|
||||
|
||||
# initial model
|
||||
depth = 10.0
|
||||
vel_init = initial_model.interp_dep(depth, field='vel')
|
||||
start = [1.25,0]; end = [1.25,2]
|
||||
vel_init_sec = initial_model.interp_sec(start, end, field='vel', val = 1)
|
||||
|
||||
# checkerboard model
|
||||
vel_ckb = ckb_model.interp_dep(depth, field='vel') # lon = [:,0], lat = [:,1], vel = [:,2]
|
||||
vel_ckb_sec = ckb_model.interp_sec(start, end, field='vel', val = 1)
|
||||
|
||||
# anisotropic arrow
|
||||
samp_interval = 3
|
||||
length = 7
|
||||
width = 0.1
|
||||
ani_thd = 0.02
|
||||
|
||||
ani_ckb_phi = ckb_model.interp_dep(depth, field='phi', samp_interval=samp_interval)
|
||||
ani_ckb_epsilon = ckb_model.interp_dep(depth, field='epsilon', samp_interval=samp_interval)
|
||||
ani_ckb = np.hstack([ani_ckb_phi, ani_ckb_epsilon[:,2].reshape(-1, 1)*length, np.ones((ani_ckb_epsilon.shape[0],1))*width]) # lon, lat, angle, length, width
|
||||
idx = np.where(ani_ckb_epsilon[:,2] > ani_thd)
|
||||
ani_ckb = ani_ckb[idx[0],:]
|
||||
|
||||
try:
|
||||
os.mkdir('img')
|
||||
except:
|
||||
pass
|
||||
|
||||
# %%
|
||||
# read src_rec_file for data
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
|
||||
sr = SrcRec.read('1_src_rec_files/src_rec_config.dat')
|
||||
station = sr.receivers[['stlo','stla','stel']].values.T
|
||||
true_loc = sr.sources[['evlo','evla','evdp']].values.T
|
||||
earthquake = true_loc
|
||||
|
||||
sr = SrcRec.read('OUTPUT_FILES/OUTPUT_FILES_signal/src_rec_file_forward_errloc.dat')
|
||||
init_loc = sr.sources[['evlo','evla','evdp']].values.T
|
||||
|
||||
# %%
|
||||
# categorize earthquakes
|
||||
ev_idx1 = []
|
||||
ev_idx2 = []
|
||||
ev_idx3 = []
|
||||
for i in range(earthquake.shape[1]):
|
||||
dep = earthquake[2,i]
|
||||
if dep < 15:
|
||||
ev_idx1.append(i)
|
||||
elif dep < 25:
|
||||
ev_idx2.append(i)
|
||||
elif dep < 35:
|
||||
ev_idx3.append(i)
|
||||
|
||||
# %%
|
||||
# plot the model setting
|
||||
fig = pygmt.Figure()
|
||||
|
||||
region = [0,2,0,2]
|
||||
frame = ["xa1","ya1"]
|
||||
projection = "M10c"
|
||||
spacing = 0.04
|
||||
|
||||
vel_range = 20
|
||||
|
||||
# -------------- initial model and earthquake location --------------
|
||||
fig.basemap(region=region, frame=["xa1","ya1","+tInitial model and locations"], projection=projection)
|
||||
# velocity perturbation
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-vel_range, vel_range], background=True, reverse=False)
|
||||
x = vel_init[:,0]; y = vel_init[:,1]; value = (vel_init[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(grid = grid)
|
||||
# earthquakes
|
||||
fig.plot(x = init_loc[0,ev_idx1], y = init_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = init_loc[0,ev_idx2], y = init_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = init_loc[0,ev_idx3], y = init_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
# stations
|
||||
fig.plot(x = station[0,:], y = station[1,:], style = "t0.4c", fill = "blue", pen = "black", label = "Station")
|
||||
|
||||
# # anisotropic arrow
|
||||
# fig.plot(ani_ckb, style='j', fill='yellow1', pen='0.5p,black')
|
||||
|
||||
fig.shift_origin(xshift=11)
|
||||
|
||||
fig.basemap(region=[0,40,0,2], frame=["xa20+lDepth (km)","ya1","Nswe"], projection="X2c/10c")
|
||||
x = vel_init_sec[:,3]; y = vel_init_sec[:,1]; value = (vel_init_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="1/0.04",region=[0,40,0,2])
|
||||
fig.grdimage(grid = grid)
|
||||
|
||||
# earthquakes
|
||||
fig.plot(x = init_loc[2,ev_idx1], y = init_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = init_loc[2,ev_idx2], y = init_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = init_loc[2,ev_idx3], y = init_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
|
||||
fig.shift_origin(xshift=4)
|
||||
|
||||
|
||||
# -------------- true model and earthquake location --------------
|
||||
fig.basemap(region=region, frame=["xa1","ya1","+tTrue model and locations"], projection=projection)
|
||||
# velocity perturbation
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-vel_range, vel_range], background=True, reverse=False)
|
||||
x = vel_ckb[:,0]; y = vel_ckb[:,1]; value = (vel_ckb[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(grid = grid)
|
||||
# earthquakes
|
||||
fig.plot(x = true_loc[0,ev_idx1], y = true_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = true_loc[0,ev_idx2], y = true_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = true_loc[0,ev_idx3], y = true_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
# stations
|
||||
# fig.plot(x = loc_st[0,:], y = loc_st[1,:], style = "t0.4c", fill = "blue", pen = "black", label = "Station")
|
||||
|
||||
# anisotropic arrow
|
||||
fig.plot(ani_ckb, style='j', fill='yellow1', pen='0.5p,black')
|
||||
|
||||
fig.shift_origin(xshift=11)
|
||||
|
||||
fig.basemap(region=[0,40,0,2], frame=["xa20+lDepth (km)","ya1","Nswe"], projection="X2c/10c")
|
||||
x = vel_ckb_sec[:,3]; y = vel_ckb_sec[:,1]; value = (vel_ckb_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="1/0.04",region=[0,40,0,2])
|
||||
fig.grdimage(grid = grid)
|
||||
|
||||
# earthquakes
|
||||
fig.plot(x = true_loc[2,ev_idx1], y = true_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = true_loc[2,ev_idx2], y = true_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = true_loc[2,ev_idx3], y = true_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
|
||||
# ------------------- colorbar -------------------
|
||||
fig.shift_origin(xshift=-11, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a%f"%(vel_range),"x+ldlnVp (%)"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.shift_origin(xshift=6, yshift=-1)
|
||||
fig.basemap(region=[0,1,0,1], frame=["wesn"], projection="X6c/1.5c")
|
||||
ani = [
|
||||
[0.2, 0.6, 45, 0.02*length, width], # lon, lat, phi, epsilon, size
|
||||
[0.5, 0.6, 45, 0.05*length, width],
|
||||
[0.8, 0.6, 45, 0.10*length, width],
|
||||
]
|
||||
fig.plot(ani, style='j', fill='yellow1', pen='0.5p,black')
|
||||
fig.text(text=["0.02", "0.05", "0.10"], x=[0.2,0.5,0.8], y=[0.2]*3, font="16p,Helvetica", justify="CM")
|
||||
fig.shift_origin(xshift= 11, yshift=2.5)
|
||||
|
||||
fig.show()
|
||||
fig.savefig('img/model_setting.png', dpi=300)
|
||||
|
||||
# %%
|
||||
# plot the joint inversion results
|
||||
|
||||
fig = pygmt.Figure()
|
||||
|
||||
region = [0,2,0,2]
|
||||
projection = "M10c"
|
||||
spacing = 0.04
|
||||
|
||||
vel_range = 20
|
||||
|
||||
tag_list = ["joint_step1", "joint_step2", "joint_step3"]
|
||||
|
||||
for itag, tag in enumerate(tag_list):
|
||||
|
||||
if (tag == "joint_step1"):
|
||||
# model
|
||||
x = vel_init[:,0]; y = vel_init[:,1]; value = (vel_init[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
x_sec = vel_init_sec[:,3]; y_sec = vel_init_sec[:,1]; value_sec = (vel_init_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
|
||||
# location
|
||||
sr = SrcRec.read('OUTPUT_FILES/OUTPUT_FILES_%s/src_rec_file_reloc_0050.dat'%(tag))
|
||||
re_loc = sr.sources[['evlo','evla','evdp']].values.T
|
||||
|
||||
frame = ["xa1","ya1","+tStep %d, preliminary location"%(itag+1)]
|
||||
elif (tag == "joint_step2"):
|
||||
# model
|
||||
data_file = "OUTPUT_FILES/OUTPUT_FILES_%s/final_model.h5"%(tag)
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
inv_model = model.to_xarray()
|
||||
vel_inv = inv_model.interp_dep(depth, field='vel') # lon = [:,0], lat = [:,1], vel = [:,2]
|
||||
x = vel_inv[:,0]; y = vel_inv[:,1]; value = (vel_inv[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
vel_inv_sec = inv_model.interp_sec(start, end, field='vel', val = 1)
|
||||
x_sec = vel_inv_sec[:,3]; y_sec = vel_inv_sec[:,1]; value_sec = (vel_inv_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
|
||||
ani_inv_phi = inv_model.interp_dep(depth, field='phi', samp_interval=samp_interval)
|
||||
ani_inv_epsilon = inv_model.interp_dep(depth, field='epsilon', samp_interval=samp_interval)
|
||||
ani_inv = np.hstack([ani_inv_phi, ani_inv_epsilon[:,2].reshape(-1, 1)*length, np.ones((ani_inv_epsilon.shape[0],1))*width]) # lon, lat, angle, length, width
|
||||
idx = np.where(ani_inv_epsilon[:,2] > ani_thd)
|
||||
ani = ani_inv[idx[0],:]
|
||||
|
||||
# location
|
||||
sr = SrcRec.read('OUTPUT_FILES/OUTPUT_FILES_%s/src_rec_file_inv_0039_reloc_0039.dat'%(tag))
|
||||
re_loc = sr.sources[['evlo','evla','evdp']].values.T
|
||||
|
||||
frame = ["xa1","ya1","+tStep %d, joint inversion"%(itag+1)]
|
||||
elif (tag == "joint_step3"):
|
||||
|
||||
# model
|
||||
x = vel_inv[:,0]; y = vel_inv[:,1]; value = (vel_inv[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
x_sec = vel_inv_sec[:,3]; y_sec = vel_inv_sec[:,1]; value_sec = (vel_inv_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100
|
||||
ani = ani_inv[idx[0],:]
|
||||
|
||||
# location
|
||||
sr = SrcRec.read('OUTPUT_FILES/OUTPUT_FILES_%s/src_rec_file_reloc_0100.dat'%(tag))
|
||||
re_loc = sr.sources[['evlo','evla','evdp']].values.T
|
||||
|
||||
frame = ["xa1","ya1","+tStep %d, relocation"%(itag+1)]
|
||||
|
||||
# plot the inversion result
|
||||
|
||||
|
||||
# -------------- inversion model --------------
|
||||
fig.basemap(region=region, frame=frame, projection=projection)
|
||||
# velocity perturbation
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-vel_range, vel_range], background=True, reverse=False)
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(grid = grid)
|
||||
# earthquakes
|
||||
fig.plot(x = re_loc[0,ev_idx1], y = re_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = re_loc[0,ev_idx2], y = re_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = re_loc[0,ev_idx3], y = re_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
# stations
|
||||
# fig.plot(x = loc_st[0,:], y = loc_st[1,:], style = "t0.4c", fill = "blue", pen = "black", label = "Station")
|
||||
|
||||
# anisotropic arrow
|
||||
if (tag == "joint_step2" or tag == "joint_step3"):
|
||||
fig.plot(ani, style='j', fill='yellow1', pen='0.5p,black')
|
||||
|
||||
fig.shift_origin(xshift=11)
|
||||
|
||||
fig.basemap(region=[0,40,0,2], frame=["xa20+lDepth (km)","ya1","Nswe"], projection="X2c/10c")
|
||||
grid = pygmt.surface(x=x_sec, y=y_sec, z=value_sec, spacing="1/0.04",region=[0,40,0,2])
|
||||
fig.grdimage(grid = grid)
|
||||
|
||||
# earthquakes
|
||||
fig.plot(x = re_loc[2,ev_idx1], y = re_loc[1,ev_idx1], style = "c0.1c", fill = "red")
|
||||
fig.plot(x = re_loc[2,ev_idx2], y = re_loc[1,ev_idx2], style = "c0.1c", fill = "green")
|
||||
fig.plot(x = re_loc[2,ev_idx3], y = re_loc[1,ev_idx3], style = "c0.1c", fill = "black")
|
||||
|
||||
fig.shift_origin(xshift=4)
|
||||
|
||||
# ------------------- colorbar -------------------
|
||||
fig.shift_origin(xshift=-4)
|
||||
|
||||
fig.shift_origin(xshift=-11, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a%f"%(vel_range),"x+ldlnVp (%)"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.shift_origin(xshift=6, yshift=-1)
|
||||
fig.basemap(region=[0,1,0,1], frame=["wesn"], projection="X6c/1.5c")
|
||||
ani = [
|
||||
[0.2, 0.6, 45, 0.02*length, width], # lon, lat, phi, epsilon, size
|
||||
[0.5, 0.6, 45, 0.05*length, width],
|
||||
[0.8, 0.6, 45, 0.10*length, width],
|
||||
]
|
||||
fig.plot(ani, style='j', fill='yellow1', pen='0.5p,black')
|
||||
fig.text(text=["0.02", "0.05", "0.10"], x=[0.2,0.5,0.8], y=[0.2]*3, font="16p,Helvetica", justify="CM")
|
||||
fig.shift_origin(xshift= 11, yshift=2.5)
|
||||
|
||||
|
||||
fig.show()
|
||||
fig.savefig('img/model_joint.png', dpi=300)
|
||||
|
||||
|
||||
63
examples/eg3_joint_inversion/prepare_input_files.py
Normal file
63
examples/eg3_joint_inversion/prepare_input_files.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# download src_ref_files from Zenodo
|
||||
import os
|
||||
import numpy as np
|
||||
import sys
|
||||
try:
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.checkerboard import Checker
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
except:
|
||||
print("ERROR: ATTModel not found. Please install pytomoatt first."
|
||||
"See https://tomoatt.github.io/PyTomoATT/installation.html for details.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
class BuildInitialModel():
|
||||
def __init__(self, par_file="./3_input_params/input_params_signal.yaml", output_dir="2_models"):
|
||||
"""
|
||||
Build initial model for tomography inversion
|
||||
"""
|
||||
self.am = ATTModel(par_file)
|
||||
self.output_dir = output_dir
|
||||
|
||||
def build_initial_model(self, vel_min=5.0, vel_max=8.0):
|
||||
"""
|
||||
Build initial model for tomography inversion
|
||||
"""
|
||||
self.am.vel[self.am.depths < 0, :, :] = vel_min
|
||||
idx = np.where((0 <= self.am.depths) & (self.am.depths < 40.0))[0]
|
||||
self.am.vel[idx, :, :] = np.linspace(vel_min, vel_max, idx.size)[::-1][:, np.newaxis, np.newaxis]
|
||||
self.am.vel[self.am.depths >= 40.0, :, :] = vel_max
|
||||
|
||||
|
||||
def build_ckb_model(output_dir="2_models"):
|
||||
cbk = Checker(f'{output_dir}/model_init_N61_61_61.h5', para_fname="./3_input_params/input_params_signal.yaml")
|
||||
cbk.checkerboard(
|
||||
n_pert_x=2, n_pert_y=2, n_pert_z=2,
|
||||
pert_vel=0.2, pert_ani=0.1, ani_dir=60.0,
|
||||
lim_x=[0.5, 1.5], lim_y=[0.5, 1.5], lim_z=[0, 40]
|
||||
)
|
||||
cbk.write(f'{output_dir}/model_ckb_N61_61_61.h5')
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# download src_rec_config.dat
|
||||
url = 'https://zenodo.org/records/14053821/files/src_rec_config.dat'
|
||||
path = "1_src_rec_files/src_rec_config.dat"
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
if not os.path.exists(path):
|
||||
sr = SrcRec.read(url)
|
||||
sr.write(path)
|
||||
|
||||
# build initial model
|
||||
output_dir = "2_models"
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
bim = BuildInitialModel(output_dir=output_dir)
|
||||
bim.build_initial_model()
|
||||
bim.am.write('{}/model_init_N{:d}_{:d}_{:d}.h5'.format(bim.output_dir, *bim.am.n_rtp))
|
||||
|
||||
# build ckb model
|
||||
build_ckb_model(output_dir)
|
||||
|
||||
|
||||
|
||||
40
examples/eg3_joint_inversion/run_this_example.sh
Normal file
40
examples/eg3_joint_inversion/run_this_example.sh
Normal file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
# Step 1: Generate necessary input files
|
||||
python prepare_input_files.py
|
||||
|
||||
# Step 2: Run forward modeling
|
||||
# # for WSL
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_signal.yaml
|
||||
# # for Linux
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_signal.yaml
|
||||
# for conda install
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_signal.yaml
|
||||
|
||||
# Step 3: Assign data noise and location perturbation to the observational data
|
||||
python assign_gaussian_noise.py
|
||||
|
||||
# Step 4: Do joint inversion
|
||||
# # for WSL
|
||||
# # step 1. relocation for 50 iterations in the initial model, using traveltimes and common-receiver differential arrival times
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_joint_step1.yaml
|
||||
# # step 2. simultaneously update model parameters and locations for 40 iterations,
|
||||
# # using traveltimes and common-source differential arrival times for model update
|
||||
# # using traveltimes and common-receiver differential arrival times for location
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_joint_step2.yaml
|
||||
# # step 3. relocation for 50 iterations in the initial model, using only common-receiver differential arrival times
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_joint_step3.yaml
|
||||
|
||||
# # for Linux
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_joint_step1.yaml
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_joint_step2.yaml
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_joint_step3.yaml
|
||||
|
||||
# for conda install
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_joint_step1.yaml
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_joint_step2.yaml
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_joint_step3.yaml
|
||||
|
||||
# Step 5 (Optional): Plot the results
|
||||
python plot_output.py
|
||||
@@ -0,0 +1,215 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-10, 50] # depth in km
|
||||
min_max_lat: [0, 2] # latitude in degree
|
||||
min_max_lon: [0, 2] # longitude in degree
|
||||
n_rtp: [61, 61, 61] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: OUTPUT_FILES/OUTPUT_FILES_1dinv_signal/src_rec_file_step_0000.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver (only valid for regional source and receiver, those of tele remain unchanged)
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_init_N61_61_61.h5 # path to initial model file
|
||||
# model_1d_name: dummy_model_1d_name # 1D model name used in teleseismic 2D solver (iasp91, ak135, user_defined is available), defined in include/1d_model.h
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
nproc_sub: 1 # number of processors for sweep parallelization (parallel the fast sweep method)
|
||||
use_gpu: false # true if use gpu (EXPERIMENTAL)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_1dinv_inv # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_source_field: true # True: output the traveltime field and adjoint field of all sources at each iteration. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_kernel: false # True: output sensitivity kernel and kernel density. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_final_model: true # True: output merged final model. This file can be used as the input model for TomoATT. Default: true. File: 'model_final.h5'.
|
||||
output_middle_model: false # True: output merged intermediate models during inversion. This file can be used as the input model for TomoATT. Default: false. File: 'middle_model_step_XXXX.h5'
|
||||
output_in_process: false # True: output at each inv iteration, otherwise, only output step 0, Niter-1, Niter. Default: true. File: 'out_data_sim_group_0'.
|
||||
output_in_process_data: false # True: output src_rec_file at each inv iteration, otherwise, only output step 0, Niter-2, Niter-1. Default: true. File: 'src_rec_file_step_XXXX.dat'
|
||||
single_precision_output: false # True: output results in single precision. Default: false.
|
||||
verbose_output_level: 0 # output internal parameters, (to do).
|
||||
output_file_format: 0 # 0: hdf5, 1: ascii
|
||||
|
||||
# output files:
|
||||
# File: 'out_data_grid.h5'. Keys: ['Mesh']['elem_conn'], element index;
|
||||
# ['Mesh']['node_coords_p'], phi coordinates of nodes;
|
||||
# ['Mesh']['node_coords_t'], theta coordinates of nodes;
|
||||
# ['Mesh']['node_coords_r'], r coordinates of nodes;
|
||||
# ['Mesh']['node_coords_x'], phi coordinates of elements;
|
||||
# ['Mesh']['node_coords_y'], theta coordinates of elements;
|
||||
# ['Mesh']['node_coords_z'], r coordinates of elements;
|
||||
# File: 'out_data_sim_group_0'. Keys: ['model']['vel_inv_XXXX'], velocity model at iteration XXXX;
|
||||
# ['model']['xi_inv_XXXX'], xi model at iteration XXXX;
|
||||
# ['model']['eta_inv_XXXX'], eta model at iteration XXXX
|
||||
# ['model']['Ks_inv_XXXX'], sensitivity kernel related to slowness at iteration XXXX
|
||||
# ['model']['Kxi_inv_XXXX'], sensitivity kernel related to xi at iteration XXXX
|
||||
# ['model']['Keta_inv_XXXX'], sensitivity kernel related to eta at iteration XXXX
|
||||
# ['model']['Ks_density_inv_XXXX'], kernel density of Ks at iteration XXXX
|
||||
# ['model']['Kxi_density_inv_XXXX'], kernel density of Kxi at iteration XXXX
|
||||
# ['model']['Keta_density_inv_XXXX'], kernel density of Keta at iteration XXXX
|
||||
# ['model']['Ks_over_Kden_inv_XXXX'], slowness kernel over kernel density at iteration XXXX
|
||||
# ['model']['Kxi_over_Kden_inv_XXXX'], xi kernel over kernel density at iteration XXXX
|
||||
# ['model']['Keta_over_Kden_inv_XXXX'], eta kernel over kernel density at iteration XXXX
|
||||
# ['model']['Ks_update_inv_XXXX'], slowness kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Kxi_update_inv_XXXX'], xi kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Keta_update_inv_XXXX'], eta kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['1dinv']['vel_1dinv_inv_XXXX'], 2d velocity model at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['r_1dinv'], r coordinates (depth), in 1d inversion mode
|
||||
# ['1dinv']['t_1dinv'], t coordinates (epicenter distance), in 1d inversion mode
|
||||
# File: 'src_rec_file_step_XXXX.dat' or 'src_rec_file_forward.dat'. The synthetic traveltime data file.
|
||||
# File: 'final_model.h5'. Keys: ['eta'], ['xi'], ['vel'], the final model.
|
||||
# File: 'middle_model_step_XXXX.h5'. Keys: ['eta'], ['xi'], ['vel'], the model at step XXXX.
|
||||
# File: 'inversion_grid.txt'. The location of inversion grid nodes
|
||||
# File: 'objective_function.txt'. The objective function value at each iteration
|
||||
# File: 'out_data_sim_group_X'. Keys: ['src_YYYY']['time_field_inv_XXXX'], traveltime field of source YYYY at iteration XXXX;
|
||||
# ['src_YYYY']['adjoint_field_inv_XXXX'], adjoint field of source YYYY at iteration XXXX;
|
||||
# ['1dinv']['time_field_1dinv_YYYY_inv_XXXX'], 2d traveltime field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['adjoint_field_1dinv_YYYY_inv_XXXX'], 2d adjoint field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
# 4 for 1d model inversion
|
||||
run_mode: 4
|
||||
|
||||
have_tele_data: false # An error will be reported if false but source out of study region is used. Default: false.
|
||||
|
||||
###################################################
|
||||
# model update parameters setting #
|
||||
###################################################
|
||||
model_update:
|
||||
max_iterations: 200 # maximum number of inversion iterations
|
||||
optim_method: 0 # optimization method. 0 : grad_descent, 1 : halve-stepping, 2 : lbfgs (EXPERIMENTAL)
|
||||
|
||||
#common parameters for all optim methods
|
||||
step_length: 0.02 # the initial step length of model perturbation. 0.01 means maximum 1% perturbation for each iteration.
|
||||
|
||||
# parameters for optim_method 0 (gradient_descent)
|
||||
optim_method_0:
|
||||
step_method: 1 # the method to modulate step size. 0: according to objective function; 1: according to gradient direction
|
||||
# if step_method:0. if objective function increase, step size -> step length * step_length_decay.
|
||||
step_length_decay: 0.9 # default: 0.9
|
||||
# if step_method:1. if the angle between the current and the previous gradients is greater than step_length_gradient_angle, step size -> step length * step_length_change[0].
|
||||
# otherwise, step size -> step length * step_length_change[1].
|
||||
step_length_gradient_angle: 120 # default: 120.0
|
||||
step_length_change: [0.5, 1.2] # default: [0.5,1.2]
|
||||
# Kdensity_coe is used to rescale the final kernel: kernel -> kernel / pow(density of kernel, Kdensity_coe). if Kdensity_coe > 0, the region with less data will be enhanced during the inversion
|
||||
# e.g., if Kdensity_coe = 0, kernel remains upchanged; if Kdensity_coe = 1, kernel is fully normalized. 0.5 or less is recommended if really required.
|
||||
Kdensity_coe: 0 # default: 0.0, limited range: 0.0 - 0.95
|
||||
|
||||
# smoothing
|
||||
smoothing:
|
||||
smooth_method: 0 # 0: multiparametrization, 1: laplacian smoothing (EXPERIMENTAL)
|
||||
l_smooth_rtp: [1, 1, 1] # smoothing coefficients for laplacian smoothing
|
||||
|
||||
# parameters for smooth method 0 (multigrid model parametrization)
|
||||
# inversion grid can be viewed in OUTPUT_FILES/inversion_grid.txt
|
||||
n_inversion_grid: 5 # number of inversion grid sets
|
||||
|
||||
uniform_inv_grid_dep: true # true if use uniform inversion grid for dep, false if use flexible inversion grid
|
||||
uniform_inv_grid_lat: true # true if use uniform inversion grid for lat, false if use flexible inversion grid
|
||||
uniform_inv_grid_lon: true # true if use uniform inversion grid for lon, false if use flexible inversion grid
|
||||
|
||||
# -------------- uniform inversion grid setting --------------
|
||||
# settings for uniform inversion grid
|
||||
n_inv_dep_lat_lon: [13, 9, 9] # number of the base inversion grid points
|
||||
min_max_dep_inv: [-10, 50] # depth in km (Radius of the earth is defined in config.h/R_earth)
|
||||
min_max_lat_inv: [0, 2] # latitude in degree
|
||||
min_max_lon_inv: [0, 2] # longitude in degree
|
||||
|
||||
# -------------- flexible inversion grid setting --------------
|
||||
# settings for flexible inversion grid
|
||||
dep_inv: [-10, 0, 10, 20, 30, 40, 50, 60] # inversion grid for vel in depth (km)
|
||||
lat_inv: [30, 30.2, 30.4, 30.6, 30.8, 31, 31.2, 31.4, 31.6, 31.8, 32] # inversion grid for vel in latitude (degree)
|
||||
lon_inv: [30, 30.2, 30.4, 30.6, 30.8, 31, 31.2, 31.4, 31.6, 31.8, 32] # inversion grid for vel in longitude (degree)
|
||||
trapezoid: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
|
||||
|
||||
# Carefully change trapezoid and trapezoid_ani, if you really want to use trapezoid inversion grid, increasing the inversion grid spacing with depth to account for the worse data coverage in greater depths.
|
||||
# The trapezoid_ inversion grid with index (i,j,k) in longitude, latitude, and depth is defined as:
|
||||
# if dep_inv[k] < trapezoid[1], lon = lon_inv[i];
|
||||
# lat = lat_inv[j];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[1] <= dep_inv[k] < trapezoid[2], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[2] <= dep_inv[k], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# The shape of trapezoid inversion gird (x) looks like:
|
||||
#
|
||||
# lon_inv[0] [1] [2] [3] [4]
|
||||
# |<-------- (lon_inv[end] - lon_inv[0]) ---->|
|
||||
# dep_inv[0] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[1] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[2] = trapezoid[1] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[3] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[4] = trapezoid[2] / x x x x x \
|
||||
# | |
|
||||
# dep_inv[5] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[6] | x x x x x |
|
||||
# |<---- trapezoid[0]* (lon_inv[end] - lon_inv[0]) ------>|
|
||||
|
||||
|
||||
# In the following data subsection, XXX_weight means a weight is assigned to the data, influencing the objective function and gradient
|
||||
# XXX_weight : [d1,d2,w1,w2] means:
|
||||
# if XXX < d1, weight = w1
|
||||
# if d1 <= XXX < d2, weight = w1 + (XXX-d1)/(d2-d1)*(w2-w1), (linear interpolation)
|
||||
# if d2 <= XXX , weight = w2
|
||||
# You can easily set w1 = w2 = 1.0 to normalize the weight related to XXX.
|
||||
# -------------- using absolute traveltime data --------------
|
||||
abs_time:
|
||||
use_abs_time: true # 'true' for using absolute traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the absolute traveltime residual (second) = abs(t^{obs}_{n,i} - t^{syn}_{n,j})
|
||||
distance_weight: [100, 200, 1, 1] # XXX is epicenter distance (km) between the source and receiver related to the data
|
||||
|
||||
# -------------- using common source differential traveltime data --------------
|
||||
cs_dif_time:
|
||||
use_cs_time: false # 'true' for using common source differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the common source differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{n,j} - t^{syn}_{n,i} + t^{syn}_{n,j}).
|
||||
azimuthal_weight: [15, 30, 1, 1] # XXX is the azimuth difference between two separate stations related to the common source.
|
||||
|
||||
# -------------- using common receiver differential traveltime data --------------
|
||||
cr_dif_time:
|
||||
use_cr_time: false # 'true' for using common receiver differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the common receiver differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{m,i} - t^{syn}_{n,i} + t^{syn}_{m,i})
|
||||
azimuthal_weight: [15, 30, 1, 1] # XXX is the azimuth difference between two separate sources related to the common receiver.
|
||||
|
||||
# -------------- global weight of different types of data (to balance the weight of different data) --------------
|
||||
global_weight:
|
||||
balance_data_weight: false # yes: over the total weight of the each type of the data. no: use original weight (below weight for each type of data needs to be set)
|
||||
abs_time_weight: 1 # weight of absolute traveltime data after balance, default: 1.0
|
||||
cs_dif_time_local_weight: 1 # weight of common source differential traveltime data after balance, default: 1.0
|
||||
cr_dif_time_local_weight: 1 # weight of common receiver differential traveltime data after balance, default: 1.0
|
||||
teleseismic_weight: 1 # weight of teleseismic data after balance, default: 1.0 (exclude in this version)
|
||||
|
||||
# -------------- inversion parameters --------------
|
||||
update_slowness : true # update slowness (velocity) or not. default: true
|
||||
update_azi_ani : false # update azimuthal anisotropy (xi, eta) or not. default: false
|
||||
@@ -0,0 +1,215 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-10, 50] # depth in km
|
||||
min_max_lat: [0, 2] # latitude in degree
|
||||
min_max_lon: [0, 2] # longitude in degree
|
||||
n_rtp: [61, 61, 61] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: 1_src_rec_files/src_rec_config.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver (only valid for regional source and receiver, those of tele remain unchanged)
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_ckb_N61_61_61.h5 # path to initial model file
|
||||
# model_1d_name: dummy_model_1d_name # 1D model name used in teleseismic 2D solver (iasp91, ak135, user_defined is available), defined in include/1d_model.h
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
nproc_sub: 1 # number of processors for sweep parallelization (parallel the fast sweep method)
|
||||
use_gpu: false # true if use gpu (EXPERIMENTAL)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_1dinv_signal # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_source_field: false # True: output the traveltime field and adjoint field of all sources at each iteration. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_kernel: false # True: output sensitivity kernel and kernel density. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_final_model: true # True: output merged final model. This file can be used as the input model for TomoATT. Default: true. File: 'model_final.h5'.
|
||||
output_middle_model: false # True: output merged intermediate models during inversion. This file can be used as the input model for TomoATT. Default: false. File: 'middle_model_step_XXXX.h5'
|
||||
output_in_process: false # True: output at each inv iteration, otherwise, only output step 0, Niter-1, Niter. Default: true. File: 'out_data_sim_group_0'.
|
||||
output_in_process_data: false # True: output src_rec_file at each inv iteration, otherwise, only output step 0, Niter-2, Niter-1. Default: true. File: 'src_rec_file_step_XXXX.dat'
|
||||
single_precision_output: false # True: output results in single precision. Default: false.
|
||||
verbose_output_level: 0 # output internal parameters, (to do).
|
||||
output_file_format: 0 # 0: hdf5, 1: ascii
|
||||
|
||||
# output files:
|
||||
# File: 'out_data_grid.h5'. Keys: ['Mesh']['elem_conn'], element index;
|
||||
# ['Mesh']['node_coords_p'], phi coordinates of nodes;
|
||||
# ['Mesh']['node_coords_t'], theta coordinates of nodes;
|
||||
# ['Mesh']['node_coords_r'], r coordinates of nodes;
|
||||
# ['Mesh']['node_coords_x'], phi coordinates of elements;
|
||||
# ['Mesh']['node_coords_y'], theta coordinates of elements;
|
||||
# ['Mesh']['node_coords_z'], r coordinates of elements;
|
||||
# File: 'out_data_sim_group_0'. Keys: ['model']['vel_inv_XXXX'], velocity model at iteration XXXX;
|
||||
# ['model']['xi_inv_XXXX'], xi model at iteration XXXX;
|
||||
# ['model']['eta_inv_XXXX'], eta model at iteration XXXX
|
||||
# ['model']['Ks_inv_XXXX'], sensitivity kernel related to slowness at iteration XXXX
|
||||
# ['model']['Kxi_inv_XXXX'], sensitivity kernel related to xi at iteration XXXX
|
||||
# ['model']['Keta_inv_XXXX'], sensitivity kernel related to eta at iteration XXXX
|
||||
# ['model']['Ks_density_inv_XXXX'], kernel density of Ks at iteration XXXX
|
||||
# ['model']['Kxi_density_inv_XXXX'], kernel density of Kxi at iteration XXXX
|
||||
# ['model']['Keta_density_inv_XXXX'], kernel density of Keta at iteration XXXX
|
||||
# ['model']['Ks_over_Kden_inv_XXXX'], slowness kernel over kernel density at iteration XXXX
|
||||
# ['model']['Kxi_over_Kden_inv_XXXX'], xi kernel over kernel density at iteration XXXX
|
||||
# ['model']['Keta_over_Kden_inv_XXXX'], eta kernel over kernel density at iteration XXXX
|
||||
# ['model']['Ks_update_inv_XXXX'], slowness kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Kxi_update_inv_XXXX'], xi kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Keta_update_inv_XXXX'], eta kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['1dinv']['vel_1dinv_inv_XXXX'], 2d velocity model at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['r_1dinv'], r coordinates (depth), in 1d inversion mode
|
||||
# ['1dinv']['t_1dinv'], t coordinates (epicenter distance), in 1d inversion mode
|
||||
# File: 'src_rec_file_step_XXXX.dat' or 'src_rec_file_forward.dat'. The synthetic traveltime data file.
|
||||
# File: 'final_model.h5'. Keys: ['eta'], ['xi'], ['vel'], the final model.
|
||||
# File: 'middle_model_step_XXXX.h5'. Keys: ['eta'], ['xi'], ['vel'], the model at step XXXX.
|
||||
# File: 'inversion_grid.txt'. The location of inversion grid nodes
|
||||
# File: 'objective_function.txt'. The objective function value at each iteration
|
||||
# File: 'out_data_sim_group_X'. Keys: ['src_YYYY']['time_field_inv_XXXX'], traveltime field of source YYYY at iteration XXXX;
|
||||
# ['src_YYYY']['adjoint_field_inv_XXXX'], adjoint field of source YYYY at iteration XXXX;
|
||||
# ['1dinv']['time_field_1dinv_YYYY_inv_XXXX'], 2d traveltime field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['adjoint_field_1dinv_YYYY_inv_XXXX'], 2d adjoint field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
# 4 for 1d model inversion
|
||||
run_mode: 4
|
||||
|
||||
have_tele_data: false # An error will be reported if false but source out of study region is used. Default: false.
|
||||
|
||||
###################################################
|
||||
# model update parameters setting #
|
||||
###################################################
|
||||
model_update:
|
||||
max_iterations: 1 # maximum number of inversion iterations
|
||||
optim_method: 0 # optimization method. 0 : grad_descent, 1 : halve-stepping, 2 : lbfgs (EXPERIMENTAL)
|
||||
|
||||
#common parameters for all optim methods
|
||||
step_length: 0.02 # the initial step length of model perturbation. 0.01 means maximum 1% perturbation for each iteration.
|
||||
|
||||
# parameters for optim_method 0 (gradient_descent)
|
||||
optim_method_0:
|
||||
step_method: 1 # the method to modulate step size. 0: according to objective function; 1: according to gradient direction
|
||||
# if step_method:0. if objective function increase, step size -> step length * step_length_decay.
|
||||
step_length_decay: 0.9 # default: 0.9
|
||||
# if step_method:1. if the angle between the current and the previous gradients is greater than step_length_gradient_angle, step size -> step length * step_length_change[0].
|
||||
# otherwise, step size -> step length * step_length_change[1].
|
||||
step_length_gradient_angle: 120 # default: 120.0
|
||||
step_length_change: [0.5, 1.2] # default: [0.5,1.2]
|
||||
# Kdensity_coe is used to rescale the final kernel: kernel -> kernel / pow(density of kernel, Kdensity_coe). if Kdensity_coe > 0, the region with less data will be enhanced during the inversion
|
||||
# e.g., if Kdensity_coe = 0, kernel remains upchanged; if Kdensity_coe = 1, kernel is fully normalized. 0.5 or less is recommended if really required.
|
||||
Kdensity_coe: 0 # default: 0.0, limited range: 0.0 - 0.95
|
||||
|
||||
# smoothing
|
||||
smoothing:
|
||||
smooth_method: 0 # 0: multiparametrization, 1: laplacian smoothing (EXPERIMENTAL)
|
||||
l_smooth_rtp: [1, 1, 1] # smoothing coefficients for laplacian smoothing
|
||||
|
||||
# parameters for smooth method 0 (multigrid model parametrization)
|
||||
# inversion grid can be viewed in OUTPUT_FILES/inversion_grid.txt
|
||||
n_inversion_grid: 5 # number of inversion grid sets
|
||||
|
||||
uniform_inv_grid_dep: false # true if use uniform inversion grid for dep, false if use flexible inversion grid
|
||||
uniform_inv_grid_lat: true # true if use uniform inversion grid for lat, false if use flexible inversion grid
|
||||
uniform_inv_grid_lon: true # true if use uniform inversion grid for lon, false if use flexible inversion grid
|
||||
|
||||
# -------------- uniform inversion grid setting --------------
|
||||
# settings for uniform inversion grid
|
||||
n_inv_dep_lat_lon: [12, 9, 9] # number of the base inversion grid points
|
||||
min_max_dep_inv: [-10, 50] # depth in km (Radius of the earth is defined in config.h/R_earth)
|
||||
min_max_lat_inv: [0, 2] # latitude in degree
|
||||
min_max_lon_inv: [0, 2] # longitude in degree
|
||||
|
||||
# -------------- flexible inversion grid setting --------------
|
||||
# settings for flexible inversion grid
|
||||
dep_inv: [-10, 0, 10, 20, 30, 40, 50, 60] # inversion grid for vel in depth (km)
|
||||
lat_inv: [30, 30.2, 30.4, 30.6, 30.8, 31, 31.2, 31.4, 31.6, 31.8, 32] # inversion grid for vel in latitude (degree)
|
||||
lon_inv: [30, 30.2, 30.4, 30.6, 30.8, 31, 31.2, 31.4, 31.6, 31.8, 32] # inversion grid for vel in longitude (degree)
|
||||
trapezoid: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
|
||||
|
||||
# Carefully change trapezoid and trapezoid_ani, if you really want to use trapezoid inversion grid, increasing the inversion grid spacing with depth to account for the worse data coverage in greater depths.
|
||||
# The trapezoid_ inversion grid with index (i,j,k) in longitude, latitude, and depth is defined as:
|
||||
# if dep_inv[k] < trapezoid[1], lon = lon_inv[i];
|
||||
# lat = lat_inv[j];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[1] <= dep_inv[k] < trapezoid[2], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[2] <= dep_inv[k], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# The shape of trapezoid inversion gird (x) looks like:
|
||||
#
|
||||
# lon_inv[0] [1] [2] [3] [4]
|
||||
# |<-------- (lon_inv[end] - lon_inv[0]) ---->|
|
||||
# dep_inv[0] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[1] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[2] = trapezoid[1] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[3] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[4] = trapezoid[2] / x x x x x \
|
||||
# | |
|
||||
# dep_inv[5] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[6] | x x x x x |
|
||||
# |<---- trapezoid[0]* (lon_inv[end] - lon_inv[0]) ------>|
|
||||
|
||||
|
||||
# In the following data subsection, XXX_weight means a weight is assigned to the data, influencing the objective function and gradient
|
||||
# XXX_weight : [d1,d2,w1,w2] means:
|
||||
# if XXX < d1, weight = w1
|
||||
# if d1 <= XXX < d2, weight = w1 + (XXX-d1)/(d2-d1)*(w2-w1), (linear interpolation)
|
||||
# if d2 <= XXX , weight = w2
|
||||
# You can easily set w1 = w2 = 1.0 to normalize the weight related to XXX.
|
||||
# -------------- using absolute traveltime data --------------
|
||||
abs_time:
|
||||
use_abs_time: true # 'true' for using absolute traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the absolute traveltime residual (second) = abs(t^{obs}_{n,i} - t^{syn}_{n,j})
|
||||
distance_weight: [100, 200, 1, 1] # XXX is epicenter distance (km) between the source and receiver related to the data
|
||||
|
||||
# -------------- using common source differential traveltime data --------------
|
||||
cs_dif_time:
|
||||
use_cs_time: false # 'true' for using common source differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the common source differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{n,j} - t^{syn}_{n,i} + t^{syn}_{n,j}).
|
||||
azimuthal_weight: [15, 30, 1, 1] # XXX is the azimuth difference between two separate stations related to the common source.
|
||||
|
||||
# -------------- using common receiver differential traveltime data --------------
|
||||
cr_dif_time:
|
||||
use_cr_time: false # 'true' for using common receiver differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
residual_weight: [1, 3, 1, 1] # XXX is the common receiver differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{m,i} - t^{syn}_{n,i} + t^{syn}_{m,i})
|
||||
azimuthal_weight: [15, 30, 1, 1] # XXX is the azimuth difference between two separate sources related to the common receiver.
|
||||
|
||||
# -------------- global weight of different types of data (to balance the weight of different data) --------------
|
||||
global_weight:
|
||||
balance_data_weight: false # yes: over the total weight of the each type of the data. no: use original weight (below weight for each type of data needs to be set)
|
||||
abs_time_weight: 1 # weight of absolute traveltime data after balance, default: 1.0
|
||||
cs_dif_time_local_weight: 1 # weight of common source differential traveltime data after balance, default: 1.0
|
||||
cr_dif_time_local_weight: 1 # weight of common receiver differential traveltime data after balance, default: 1.0
|
||||
teleseismic_weight: 1 # weight of teleseismic data after balance, default: 1.0 (exclude in this version)
|
||||
|
||||
# -------------- inversion parameters --------------
|
||||
update_slowness : true # update slowness (velocity) or not. default: true
|
||||
update_azi_ani : false # update azimuthal anisotropy (xi, eta) or not. default: false
|
||||
37
examples/eg4_1d_inversion/plot_output.py
Normal file
37
examples/eg4_1d_inversion/plot_output.py
Normal file
@@ -0,0 +1,37 @@
|
||||
import h5py
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import os
|
||||
|
||||
try:
|
||||
os.mkdir("img")
|
||||
except:
|
||||
pass
|
||||
|
||||
dep = np.linspace(50,-10, 61)
|
||||
|
||||
with h5py.File("OUTPUT_FILES/OUTPUT_FILES_1dinv_inv/final_model.h5", "r") as f:
|
||||
vel_final= np.array(f["vel"])
|
||||
with h5py.File("2_models/model_init_N61_61_61.h5", "r") as f:
|
||||
vel_init = np.array(f["vel"])
|
||||
with h5py.File("2_models/model_ckb_N61_61_61.h5", "r") as f:
|
||||
vel_ckb = np.array(f["vel"])
|
||||
|
||||
fig = plt.figure(figsize=(6, 6))
|
||||
ax = fig.add_subplot(111)
|
||||
ax.plot(vel_init[:,0,0] , dep, label="init")
|
||||
ax.plot(vel_ckb[:,0,0], dep, label="ckb")
|
||||
ax.plot(vel_final[:,0,0], dep, label="inv")
|
||||
ax.grid()
|
||||
ax.set_xlabel("Velocity (m/s)",fontsize=16)
|
||||
ax.set_ylabel("Depth (km)",fontsize=16)
|
||||
ax.get_xaxis().set_tick_params(labelsize=16)
|
||||
ax.get_yaxis().set_tick_params(labelsize=16)
|
||||
ax.set_xlim([4.5,8.5])
|
||||
ax.set_ylim([0,50])
|
||||
|
||||
plt.gca().invert_yaxis()
|
||||
plt.legend(fontsize=16)
|
||||
|
||||
plt.show()
|
||||
fig.savefig("img/1d_model_inversion.png", dpi=300, bbox_inches="tight", edgecolor="w", facecolor="w")
|
||||
64
examples/eg4_1d_inversion/prepare_input_files.py
Normal file
64
examples/eg4_1d_inversion/prepare_input_files.py
Normal file
@@ -0,0 +1,64 @@
|
||||
# %%
|
||||
# download src_ref_files from Zenodo
|
||||
import os
|
||||
import numpy as np
|
||||
import sys
|
||||
try:
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.checkerboard import Checker
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
except:
|
||||
print("ERROR: ATTModel not found. Please install pytomoatt first."
|
||||
"See https://tomoatt.github.io/PyTomoATT/installation.html for details.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
class BuildInitialModel():
|
||||
def __init__(self, par_file="./3_input_params/input_params_signal.yaml", output_dir="2_models"):
|
||||
"""
|
||||
Build initial model for tomography inversion
|
||||
"""
|
||||
self.am = ATTModel(par_file)
|
||||
self.output_dir = output_dir
|
||||
|
||||
def build_initial_model(self, vel_min=5.0, vel_max=8.0):
|
||||
"""
|
||||
Build initial model for tomography inversion
|
||||
"""
|
||||
self.am.vel[self.am.depths < 0, :, :] = vel_min
|
||||
idx = np.where((0 <= self.am.depths) & (self.am.depths < 40.0))[0]
|
||||
self.am.vel[idx, :, :] = np.linspace(vel_min, vel_max, idx.size)[::-1][:, np.newaxis, np.newaxis]
|
||||
self.am.vel[self.am.depths >= 40.0, :, :] = vel_max
|
||||
|
||||
def build_ckb_model(self):
|
||||
"""
|
||||
Build checkerboard model for tomography inversion
|
||||
"""
|
||||
nr = self.am.n_rtp[0]
|
||||
for ir in range(nr):
|
||||
dep = self.am.depths[ir]
|
||||
self.am.vel[ir, :, :] = (1 + 0.05 * np.sin(np.pi * dep / 10.0)) * self.am.vel[ir, :, :]
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# download src_rec_config.dat
|
||||
url = 'https://zenodo.org/records/14053821/files/src_rec_config.dat'
|
||||
path = "1_src_rec_files/src_rec_config.dat"
|
||||
os.makedirs(os.path.dirname(path), exist_ok=True)
|
||||
if not os.path.exists(path):
|
||||
sr = SrcRec.read(url)
|
||||
sr.write(path)
|
||||
|
||||
# build initial model
|
||||
output_dir = "2_models"
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
bim = BuildInitialModel(output_dir=output_dir)
|
||||
bim.build_initial_model()
|
||||
bim.am.write('{}/model_init_N{:d}_{:d}_{:d}.h5'.format(bim.output_dir, *bim.am.n_rtp))
|
||||
|
||||
bim.build_ckb_model()
|
||||
bim.am.write('{}/model_ckb_N{:d}_{:d}_{:d}.h5'.format(bim.output_dir, *bim.am.n_rtp))
|
||||
|
||||
|
||||
|
||||
27
examples/eg4_1d_inversion/run_this_example.sh
Normal file
27
examples/eg4_1d_inversion/run_this_example.sh
Normal file
@@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
# Step 1: Generate necessary input files
|
||||
echo "Generating TomoATT input files..."
|
||||
python prepare_input_files.py
|
||||
|
||||
# Step 2: Run forward modeling
|
||||
# # for WSL
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_1dinv_signal.yaml
|
||||
# # for Linux
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_1dinv_signal.yaml
|
||||
# for conda install
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_1dinv_signal.yaml
|
||||
|
||||
# Step 3: Do inversion
|
||||
# # for WSL
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_1dinv_inv.yaml
|
||||
# # for Linux
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_1dinv_inv.yaml
|
||||
# for conda install
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_1dinv_inv.yaml
|
||||
|
||||
# Step 4 (Optional): Plot the results
|
||||
echo "Plotting the results..."
|
||||
python plot_output.py
|
||||
|
||||
BIN
examples/realcase1_regional_tomography_California/.DS_Store
vendored
Normal file
BIN
examples/realcase1_regional_tomography_California/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,186 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-5, 45] # depth in km
|
||||
min_max_lat: [-2.0, 2.4] # latitude in degree
|
||||
min_max_lon: [-0.8, 0.8] # longitude in degree
|
||||
n_rtp: [51, 89, 33] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: 1_src_rec_files/src_rec_file.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_init_N51_89_33.h5 # path to initial model file
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_inv # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_source_field: false # True: output the traveltime field and adjoint field of all sources at each iteration. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_kernel: true
|
||||
output_final_model: true # True: output merged final model. This file can be used as the input model for TomoATT. Default: true. File: 'model_final.h5'.
|
||||
output_middle_model: true # True: output merged intermediate models during inversion. This file can be used as the input model for TomoATT. Default: false. File: 'middle_model_step_XXXX.h5'
|
||||
output_in_process: true # True: output at each inv iteration, otherwise, only output step 0, Niter-1, Niter. Default: true. File: 'out_data_sim_group_0'.
|
||||
output_in_process_data: true # True: output src_rec_file at each inv iteration, otherwise, only output step 0, Niter-2, Niter-1. Default: true. File: 'src_rec_file_step_XXXX.dat'
|
||||
single_precision_output: false # True: output results in single precision. Default: false.
|
||||
verbose_output_level: 0 # output internal parameters, (to do)
|
||||
output_file_format: 0 # 0: hdf5, 1: ascii
|
||||
|
||||
# output files:
|
||||
# File: 'out_data_grid.h5'. Keys: ['Mesh']['elem_conn'], element index;
|
||||
# ['Mesh']['node_coords_p'], phi coordinates of nodes;
|
||||
# ['Mesh']['node_coords_t'], theta coordinates of nodes;
|
||||
# ['Mesh']['node_coords_r'], r coordinates of nodes;
|
||||
# ['Mesh']['node_coords_x'], phi coordinates of elements;
|
||||
# ['Mesh']['node_coords_y'], theta coordinates of elements;
|
||||
# ['Mesh']['node_coords_z'], r coordinates of elements;
|
||||
# File: 'out_data_sim_group_0'. Keys: ['model']['vel_inv_XXXX'], velocity model at iteration XXXX;
|
||||
# ['model']['xi_inv_XXXX'], xi model at iteration XXXX;
|
||||
# ['model']['eta_inv_XXXX'], eta model at iteration XXXX
|
||||
# ['model']['Ks_inv_XXXX'], sensitivity kernel related to slowness at iteration XXXX
|
||||
# ['model']['Kxi_inv_XXXX'], sensitivity kernel related to xi at iteration XXXX
|
||||
# ['model']['Keta_inv_XXXX'], sensitivity kernel related to eta at iteration XXXX
|
||||
# ['model']['Ks_density_inv_XXXX'], kernel density of Ks at iteration XXXX
|
||||
# ['model']['Kxi_density_inv_XXXX'], kernel density of Kxi at iteration XXXX
|
||||
# ['model']['Keta_density_inv_XXXX'], kernel density of Keta at iteration XXXX
|
||||
# ['model']['Ks_over_Kden_inv_XXXX'], slowness kernel over kernel density at iteration XXXX
|
||||
# ['model']['Kxi_over_Kden_inv_XXXX'], xi kernel over kernel density at iteration XXXX
|
||||
# ['model']['Keta_over_Kden_inv_XXXX'], eta kernel over kernel density at iteration XXXX
|
||||
# ['model']['Ks_update_inv_XXXX'], slowness kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Kxi_update_inv_XXXX'], xi kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Keta_update_inv_XXXX'], eta kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['1dinv']['vel_1dinv_inv_XXXX'], 2d velocity model at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['r_1dinv'], r coordinates (depth), in 1d inversion mode
|
||||
# ['1dinv']['t_1dinv'], t coordinates (epicenter distance), in 1d inversion mode
|
||||
# File: 'src_rec_file_step_XXXX.dat' or 'src_rec_file_forward.dat'. The synthetic traveltime data file.
|
||||
# File: 'final_model.h5'. Keys: ['eta'], ['xi'], ['vel'], the final model.
|
||||
# File: 'middle_model_step_XXXX.h5'. Keys: ['eta'], ['xi'], ['vel'], the model at step XXXX.
|
||||
# File: 'inversion_grid.txt'. The location of inversion grid nodes
|
||||
# File: 'objective_function.txt'. The objective function value at each iteration
|
||||
# File: 'out_data_sim_group_X'. Keys: ['src_YYYY']['time_field_inv_XXXX'], traveltime field of source YYYY at iteration XXXX;
|
||||
# ['src_YYYY']['adjoint_field_inv_XXXX'], adjoint field of source YYYY at iteration XXXX;
|
||||
# ['1dinv']['time_field_1dinv_YYYY_inv_XXXX'], 2d traveltime field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['adjoint_field_1dinv_YYYY_inv_XXXX'], 2d adjoint field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
# 4 for 1d model inversion
|
||||
run_mode: 1
|
||||
|
||||
###################################################
|
||||
# model update parameters setting #
|
||||
###################################################
|
||||
model_update:
|
||||
max_iterations: 80 # maximum number of inversion iterations
|
||||
|
||||
step_length: 0.01 # the initial step length of model perturbation. 0.01 means maximum 1% perturbation for each iteration.
|
||||
|
||||
# parameters for optim_method 0 (gradient_descent)
|
||||
optim_method_0:
|
||||
# if step_method:1. if the angle between the current and the previous gradients is greater than step_length_gradient_angle, step size -> step length * step_length_change[0].
|
||||
# otherwise, step size -> step length * step_length_change[1].
|
||||
step_length_gradient_angle: 120 # default: 120.0
|
||||
step_length_change: [0.5, 1.41] # default: [0.5,1.2]
|
||||
Kdensity_coe: 0.3 # default: 0.0, range: 0.0 - 1.0
|
||||
|
||||
# parameters for smooth method 0 (multigrid model parametrization)
|
||||
# inversion grid can be viewed in OUTPUT_FILES/inversion_grid.txt
|
||||
n_inversion_grid: 5 # number of inversion grid sets
|
||||
|
||||
uniform_inv_grid_dep: false # true if use uniform inversion grid for dep, false if use flexible inversion grid
|
||||
uniform_inv_grid_lat: false # true if use uniform inversion grid for lat, false if use flexible inversion grid
|
||||
uniform_inv_grid_lon: false # true if use uniform inversion grid for lon, false if use flexible inversion grid
|
||||
|
||||
# settings for uniform inversion grid
|
||||
n_inv_dep_lat_lon: [3, 11, 11] # number of inversion grid in depth, latitude, and longitude direction
|
||||
min_max_dep_inv: [-5 , 5] # inversion grid for vel in depth (km)
|
||||
min_max_lat_inv: [0, 1] # inversion grid for vel in latitude (degree)
|
||||
min_max_lon_inv: [0, 1] # inversion grid for vel in longitude (degree)
|
||||
|
||||
# settings for flexible inversion grid
|
||||
dep_inv: [-5, -2, 0, 3, 7, 12, 17, 23, 30, 38, 47, 57] # inversion grid for vel in depth (km)
|
||||
lat_inv: [-2.5, -2.2, -1.9, -1.6, -1.3, -1.0, -0.7, -0.4, -0.1, 0.2, 0.5, 0.8, 1.1, 1.4, 1.7, 2.0, 2.3, 2.6] # inversion grid for vel in latitude (degree)
|
||||
lon_inv: [-1.2, -0.9, -0.6, -0.3, 0, 0.3, 0.6, 0.9, 1.2] # inversion grid for vel in longitude (degree)
|
||||
trapezoid: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
|
||||
|
||||
# if we want to use another inversion grid for inverting anisotropy, set invgrid_ani: true (default: false)
|
||||
invgrid_ani: true
|
||||
|
||||
# ---------- flexible inversion grid setting for anisotropy ----------
|
||||
# settings for flexible inversion grid for anisotropy
|
||||
dep_inv_ani: [-5, -2, 0, 3, 7, 12, 17, 23, 30, 38, 47, 57] # inversion grid for ani in depth (km)
|
||||
lat_inv_ani: [-2.8, -2.3, -1.8, -1.3, -0.8, -0.3, 0.2, 0.7, 1.2, 1.7, 2.2, 2.7] # inversion grid for ani in latitude (degree)
|
||||
lon_inv_ani: [-1.2, -0.9, -0.6, -0.3, 0, 0.3, 0.6, 0.9, 1.2] # inversion grid for ani in longitude (degree)
|
||||
trapezoid_ani: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
|
||||
|
||||
|
||||
# Carefully change trapezoid and trapezoid_ani, if you really want to use trapezoid inversion grid, increasing the inversion grid spacing with depth to account for the worse data coverage in greater depths.
|
||||
# The trapezoid_ inversion grid with index (i,j,k) in longitude, latitude, and depth is defined as:
|
||||
# if dep_inv[k] < trapezoid[1], lon = lon_inv[i];
|
||||
# lat = lat_inv[j];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[1] <= dep_inv[k] < trapezoid[2], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[2] <= dep_inv[k], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# The shape of trapezoid inversion gird (x) looks like:
|
||||
#
|
||||
# lon_inv[0] [1] [2] [3] [4]
|
||||
# |<-------- (lon_inv[end] - lon_inv[0]) ---->|
|
||||
# dep_inv[0] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[1] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[2] = trapezoid[1] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[3] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[4] = trapezoid[2] / x x x x x \
|
||||
# | |
|
||||
# dep_inv[5] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[6] | x x x x x |
|
||||
# |<---- trapezoid[0]* (lon_inv[end] - lon_inv[0]) ------>|
|
||||
|
||||
# -------------- using absolute traveltime data --------------
|
||||
abs_time:
|
||||
use_abs_time: true # 'true' for using absolute traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- using common source differential traveltime data --------------
|
||||
cs_dif_time:
|
||||
use_cs_time: false # 'true' for using common source differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- using common receiver differential traveltime data --------------
|
||||
cr_dif_time:
|
||||
use_cr_time: false # 'true' for using common receiver differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- inversion parameters --------------
|
||||
update_slowness : true # update slowness (velocity) or not. default: true
|
||||
update_azi_ani : true # update azimuthal anisotropy (xi, eta) or not. default: false
|
||||
30
examples/realcase1_regional_tomography_California/README.md
Normal file
30
examples/realcase1_regional_tomography_California/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Real case of regional tomography in central California near Parkfield
|
||||
|
||||
This is a real case to invert traveltimes for velocity heterogeneity and azimuthal anisotropy in central California near Parkfield
|
||||
|
||||
Reference:
|
||||
|
||||
[1] J. Chen, G. Chen, M. Nagaso, and P. Tong, Adjoint-state traveltime tomography for azimuthally anisotropic media in spherical coordinates. Geophys. J. Int., 234 (2023), pp. 712-736.
|
||||
https://doi.org/10.1093/gji/ggad093
|
||||
|
||||
[2] J. Chen, M. Nagaso, M. Xu, and P. Tong, TomoATT: An open-source package for Eikonal equation-based adjoint-state traveltime tomography for seismic velocity and azimuthal anisotropy, submitted.
|
||||
https://doi.org/10.48550/arXiv.2412.00031
|
||||
|
||||
|
||||
Python modules are required to initiate the inversion and to plot final results:
|
||||
- h5py
|
||||
- PyTomoAT
|
||||
- Pygmt
|
||||
- gmt
|
||||
|
||||
Run this example:
|
||||
|
||||
1. Run bash script `bash run_this_example.sh` to execute the test.
|
||||
|
||||
2. After inversion, run `plot_output.py` to plot the results.
|
||||
|
||||
The imaging results:
|
||||
|
||||

|
||||
|
||||
|
||||
222
examples/realcase1_regional_tomography_California/plot_output.py
Normal file
222
examples/realcase1_regional_tomography_California/plot_output.py
Normal file
@@ -0,0 +1,222 @@
|
||||
# %%
|
||||
import pygmt
|
||||
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
|
||||
|
||||
import os
|
||||
|
||||
# %%
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.data import ATTData
|
||||
import numpy as np
|
||||
|
||||
# %%
|
||||
# read model files
|
||||
|
||||
Ngrid = [51,89,33]
|
||||
data_file = '2_models/model_init_N%d_%d_%d.h5'%(Ngrid[0],Ngrid[1],Ngrid[2])
|
||||
par_file = '3_input_params/input_params_real.yaml'
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
initial_model = model.to_xarray()
|
||||
|
||||
data_file = 'OUTPUT_FILES/OUTPUT_FILES_real/final_model.h5'
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
inv_model = model.to_xarray()
|
||||
|
||||
# %%
|
||||
# read earthquakes and stations
|
||||
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
|
||||
# read src_rec_file
|
||||
sr = SrcRec.read("1_src_rec_files/src_rec_file.dat")
|
||||
|
||||
# rotate back to original coordinates
|
||||
central_lat = 35.6
|
||||
central_lon = -120.45
|
||||
rotation_angle = -30
|
||||
sr.rotate(central_lat, central_lon, rotation_angle, reverse=True)
|
||||
|
||||
# get the coordinates of the stations and earthquakes
|
||||
stations = sr.receivers[['stlo','stla','stel']].values.T
|
||||
earthquakes = sr.sources[['evlo','evla','evdp']].values.T
|
||||
|
||||
print(stations.shape)
|
||||
print(earthquakes.shape)
|
||||
|
||||
# %%
|
||||
# study region
|
||||
|
||||
import sys
|
||||
sys.path.append('../utils')
|
||||
import functions_for_data as ffd
|
||||
|
||||
lat1 = -1.8; lat2 = 2.2;
|
||||
lon1 = -0.7; lon2 = 0.7;
|
||||
|
||||
lat_lon_rotate = np.array([[lon1,lat1],[lon1,lat2],[lon2,lat2],[lon2,lat1],[lon1,lat1]])
|
||||
lat_lon = ffd.rtp_rotation_reverse(lat_lon_rotate[:,1],lat_lon_rotate[:,0],central_lat,central_lon,rotation_angle)
|
||||
studt_lat = lat_lon[0]
|
||||
studt_lon = lat_lon[1]
|
||||
|
||||
# %%
|
||||
# load topography
|
||||
region = [-122.8,-118.5,33.5,38]
|
||||
grid_topo = pygmt.datasets.load_earth_relief(resolution="01m", region=region)
|
||||
grid_gra = pygmt.grdgradient(grid = grid_topo, azimuth = 0)
|
||||
|
||||
# %%
|
||||
def line_read(file):
|
||||
doc=open(file,'r')
|
||||
file = doc.readlines()
|
||||
doc.close()
|
||||
lat = []; lon = [];
|
||||
for info in file:
|
||||
tmp = info.split()
|
||||
lon.append(float(tmp[0]))
|
||||
lat.append(float(tmp[1]))
|
||||
return((lat,lon))
|
||||
|
||||
# %%
|
||||
# plot imgaing results
|
||||
|
||||
fig = pygmt.Figure()
|
||||
try:
|
||||
os.mkdir("img")
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# ------------------ Sub fig 1. topography ------------------
|
||||
region = [-122.8,-118.5,33.5,38]
|
||||
frame = ["xa1","ya1","nSWe"]
|
||||
projection = "M10c"
|
||||
|
||||
# topography
|
||||
pygmt.makecpt(cmap="globe", series=[-4000,4000], background = True)
|
||||
fig.grdimage(grid=grid_topo, shading = grid_gra, projection=projection, frame=frame,region=region)
|
||||
# study region
|
||||
fig.plot(x = studt_lon, y = studt_lat, pen = "1.5p,red")
|
||||
# earthquakes
|
||||
fig.plot(x = earthquakes[0,:], y = earthquakes[1,:], style = "c0.02c", fill = "red",label = "Earthquake")
|
||||
# stations
|
||||
fig.plot(x = stations[0,:], y = stations[1,:], style = "t0.2c", fill = "blue", pen = "white", label = "Station")
|
||||
|
||||
|
||||
fig.basemap(region=[0,1,0,1], frame=["wesn+gwhite"], projection="X4c/2c")
|
||||
fig.plot(x=0.1, y=0.3, style='c0.2c', fill='red')
|
||||
fig.text(text="Earthquake", x=0.2, y=0.3, font="16p,Helvetica", justify="LM")
|
||||
fig.plot(x=0.1, y=0.7, style='t0.4c', fill='blue', pen='black')
|
||||
fig.text(text="Station", x=0.2, y=0.7, font="16p,Helvetica", justify="LM")
|
||||
|
||||
|
||||
# ------------------ Sub fig 2. colorbar ------------------
|
||||
fig.shift_origin(xshift= 2, yshift= -2)
|
||||
|
||||
pygmt.makecpt(cmap="globe", series=[-4000,4000], background = True)
|
||||
fig.colorbar(frame = ["a%f"%(4000),"y+lElevation (m)"], position="+e+w4c/0.3c+h")
|
||||
fig.shift_origin(yshift=-2)
|
||||
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-8, 8], background=True, reverse=False)
|
||||
fig.colorbar(frame = ["a%f"%(4),"y+ldlnVp (%)"], position="+e+w4c/0.3c+h")
|
||||
fig.shift_origin(yshift=-2)
|
||||
|
||||
pygmt.makecpt(cmap="cool", series=[0, 0.08], background=True, reverse=False)
|
||||
fig.colorbar(frame = ["a%f"%(0.04),"y+lAnisotropy"], position="+ef+w4c/0.3c+h")
|
||||
|
||||
|
||||
|
||||
# ------------------ Sub fig 3. model ------------------
|
||||
fig.shift_origin(xshift = 10, yshift=8)
|
||||
|
||||
region_oblique = [-0.7,0.7,-2.2,1.8]
|
||||
projection = "OA%s/%s/%s/4c"%(central_lon,central_lat,rotation_angle-90.0)
|
||||
perspective = "30/90"
|
||||
spacing = "1m"
|
||||
|
||||
depth_list = [4,8,16]
|
||||
|
||||
for idepth, depth in enumerate(depth_list):
|
||||
|
||||
# initial model
|
||||
vel_init = initial_model.interp_dep(depth, field='vel')
|
||||
|
||||
# output model
|
||||
vel_inv = inv_model.interp_dep(depth, field='vel') # velocity
|
||||
epsilon_inv = inv_model.interp_dep(depth, field='epsilon') # magnitude of anisotropy
|
||||
|
||||
# fast velocity directions
|
||||
samp_interval = 3
|
||||
ani_thd = 0.015
|
||||
length = 20
|
||||
width = 0.1
|
||||
|
||||
ani_inv_phi = inv_model.interp_dep(depth, field='phi', samp_interval=samp_interval)
|
||||
ani_inv_epsilon = inv_model.interp_dep(depth, field='epsilon', samp_interval=samp_interval)
|
||||
ani_inv = np.hstack([ani_inv_phi, ani_inv_epsilon[:,2].reshape(-1, 1)*length, np.ones((ani_inv_epsilon.shape[0],1))*width]) # lon, lat, angle, length, width
|
||||
idx = np.where(ani_inv_epsilon[:,2] > ani_thd)
|
||||
ani = ani_inv[idx[0],:]
|
||||
|
||||
# --------- plot velocity ------------
|
||||
if idepth == 0:
|
||||
frame = ["xa100","ya1","nSwE"]
|
||||
elif idepth == len(depth_list)-1:
|
||||
frame = ["xa100","ya1","NsWe"]
|
||||
else:
|
||||
frame = ["xa100","ya1","nswe"]
|
||||
|
||||
fig.basemap(region=region_oblique, frame=frame, projection=projection, perspective=perspective)
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-8, 8], background=True, reverse=False)
|
||||
|
||||
x = vel_init[:,0]; y = vel_init[:,1]; value = (vel_inv[:,2] - vel_init[:,2])/vel_init[:,2] * 100
|
||||
y,x = ffd.rtp_rotation_reverse(y,x,central_lat,central_lon,rotation_angle)
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(frame=frame,grid = grid,projection=projection, region=region_oblique,perspective=perspective) # nan_transparent may work
|
||||
|
||||
# tectonic setting
|
||||
fig.coast(region=region_oblique, frame=frame, projection=projection, perspective=perspective, shorelines="1p,black") # coastlines
|
||||
(SAFy,SAFx) = line_read("tectonics/SAF")
|
||||
fig.plot(x = SAFx, y = SAFy, pen = '3.0p,black', perspective = perspective) # SAF
|
||||
if idepth == 0:
|
||||
fig.text(text = "SMB", x = -120.45 , y = 35.0, font = "16p,Helvetica-Bold,black", angle = 150, fill = "lightblue", perspective = perspective) # SMB
|
||||
fig.text(text = "FT", x = -120.6 , y = 36.50, font = "16p,Helvetica-Bold,black", angle = 150, fill = "lightblue", perspective = perspective) # Franciscan terrane
|
||||
fig.text(text = "ST", x = -121.1 , y = 36.0, font = "16p,Helvetica-Bold,black", angle = 150, fill = "lightblue", perspective = perspective) # Salinian terrane
|
||||
fig.text(text = "TR", x = -119.30 , y = 34.70, font = "16p,Helvetica-Bold,black", angle = 150, fill = "lightblue", perspective = perspective) # Coast Ranges
|
||||
|
||||
# depth label
|
||||
fig.text(text="%d km"%(depth), x = -119.8 , y = 34.0, font = "16p,Helvetica-Bold,black", angle = 180, fill = "white", perspective = perspective) # Coast Ranges
|
||||
|
||||
|
||||
# --------- plot anisotropy ------------
|
||||
fig.shift_origin(yshift=-12)
|
||||
|
||||
fig.basemap(region=region_oblique, frame=frame, projection=projection, perspective=perspective)
|
||||
pygmt.makecpt(cmap="cool", series=[0, 0.08], background=True)
|
||||
value = epsilon_inv[:,2]
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(frame=frame,grid = grid,projection=projection, region=region_oblique,perspective=perspective) # nan_transparent may work
|
||||
|
||||
# tectonic setting
|
||||
fig.coast(region=region_oblique, frame=frame, projection=projection, perspective=perspective, shorelines="1p,black") # coastlines
|
||||
(line_y,line_x) = line_read("tectonics/SAF_creeping")
|
||||
fig.plot(x = line_x, y = line_y, pen = '3.0p,black',perspective = perspective)
|
||||
(line_y,line_x) = line_read("tectonics/SAF_transition")
|
||||
fig.plot(x = line_x, y = line_y, pen = '3.0p,red',perspective = perspective)
|
||||
(line_y,line_x) = line_read("tectonics/SAF_locked")
|
||||
fig.plot(x = line_x, y = line_y, pen = '3.0p,blue',perspective = perspective)
|
||||
|
||||
# anisotropy
|
||||
if len(ani) > 0:
|
||||
# rotate back to original coordinates
|
||||
x = ani[:,0]; y = ani[:,1]
|
||||
y,x = ffd.rtp_rotation_reverse(y,x,central_lat,central_lon,rotation_angle)
|
||||
ani[:,0] = x; ani[:,1] = y; # no need to modify the angle, because the porjection angle and rotate angle are the same
|
||||
fig.plot(ani, style='j', fill='yellow1', pen='0.5p,black',perspective=perspective)
|
||||
|
||||
fig.shift_origin(xshift=6,yshift=12)
|
||||
|
||||
|
||||
fig.show()
|
||||
|
||||
fig.savefig("img/imaging_result.png")
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# %%
|
||||
# download src_ref_files from Zenodo
|
||||
import os
|
||||
import requests
|
||||
|
||||
url = 'https://zenodo.org/records/14065341/files/src_rec_file.dat?download=1'
|
||||
|
||||
path = "1_src_rec_files/src_rec_file.dat"
|
||||
|
||||
# check file existence
|
||||
if not os.path.exists(path):
|
||||
try:
|
||||
os.mkdir("1_src_rec_files")
|
||||
except:
|
||||
pass
|
||||
print("Downloading src_rec_file.dat from Zenodo...")
|
||||
response = requests.get(url, stream=True)
|
||||
with open(path, 'wb') as out_file:
|
||||
out_file.write(response.content)
|
||||
print("Download complete.")
|
||||
else:
|
||||
print("src_rec_file.dat already exists.")
|
||||
|
||||
# %%
|
||||
# download initial model from Zenodo
|
||||
|
||||
url = 'https://zenodo.org/records/14065341/files/model_init_N51_89_33.h5?download=1'
|
||||
|
||||
path = "2_models/model_init_N51_89_33.h5"
|
||||
|
||||
# check file existence
|
||||
if not os.path.exists(path):
|
||||
try:
|
||||
os.mkdir("2_models")
|
||||
except:
|
||||
pass
|
||||
print("Downloading model_init_N51_89_33.h5 from Zenodo...")
|
||||
response = requests.get(url, stream=True)
|
||||
with open(path, 'wb') as out_file:
|
||||
out_file.write(response.content)
|
||||
print("Download complete.")
|
||||
else:
|
||||
print("model_init_N51_89_33.h5 already exists.")
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Step 1: Generate necessary input files
|
||||
python prepare_input_files.py
|
||||
|
||||
# Step 2: Run inversion
|
||||
# # for WSL
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_real.yaml
|
||||
# for Linux
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_real.yaml
|
||||
# for conda install
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_real.yaml
|
||||
|
||||
# Step 3 (Optional): Plot the results
|
||||
python plot_output.py
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
-122.73566 37.96894
|
||||
-122.70941 37.93895
|
||||
-122.65033 37.88999
|
||||
-122.62177 37.83209
|
||||
-122.59009 37.79618
|
||||
-122.56673 37.74661
|
||||
-122.51982 37.71281
|
||||
-122.47924 37.65959
|
||||
-122.40956 37.58436
|
||||
-122.38051 37.54962
|
||||
-122.32748 37.48461
|
||||
-122.23632 37.38344
|
||||
-122.18852 37.34638
|
||||
-122.15621 37.31470
|
||||
-122.11902 37.26828
|
||||
-122.01512 37.19501
|
||||
-121.92424 37.12444
|
||||
-121.88689 37.10485
|
||||
-121.86086 37.08276
|
||||
-121.78342 37.04335
|
||||
-121.70450 36.97942
|
||||
-121.65426 36.93801
|
||||
-121.57487 36.88348
|
||||
-121.47861 36.81956
|
||||
-121.43712 36.78821
|
||||
-121.40534 36.76781
|
||||
-121.36812 36.75009
|
||||
-121.33557 36.71495
|
||||
-121.27255 36.67184
|
||||
-121.16342 36.57248
|
||||
-121.09358 36.51578
|
||||
-121.02139 36.44378
|
||||
-120.93316 36.35578
|
||||
-120.79679 36.21978
|
||||
-120.63636 36.07582
|
||||
-120.52406 35.97185
|
||||
-120.43583 35.90791
|
||||
-120.33957 35.81993
|
||||
-120.29568 35.74979
|
||||
-120.26271 35.71512
|
||||
-120.23380 35.67390
|
||||
-120.19772 35.63300
|
||||
-120.12299 35.56383
|
||||
-120.02674 35.48387
|
||||
-119.98846 35.44344
|
||||
-119.88017 35.32590
|
||||
-119.78610 35.24387
|
||||
-119.67380 35.14792
|
||||
-119.53743 35.04400
|
||||
-119.40726 34.94926
|
||||
-119.34920 34.92597
|
||||
-119.31423 34.90995
|
||||
-119.24588 34.88266
|
||||
-119.20791 34.87552
|
||||
-119.16832 34.87107
|
||||
-119.12954 34.86300
|
||||
-119.09076 34.86210
|
||||
-118.97416 34.84129
|
||||
-118.93565 34.84176
|
||||
-118.85999 34.82469
|
||||
-118.78894 34.79661
|
||||
-118.72217 34.76987
|
||||
-118.68535 34.75631
|
||||
-118.56902 34.72084
|
||||
-118.49005 34.70185
|
||||
-118.39037 34.66204
|
||||
-118.22995 34.61434
|
||||
-118.06150 34.54260
|
||||
@@ -0,0 +1,10 @@
|
||||
-121.36812 36.75009
|
||||
-121.33557 36.71495
|
||||
-121.27255 36.67184
|
||||
-121.16342 36.57248
|
||||
-121.09358 36.51578
|
||||
-121.02139 36.44378
|
||||
-120.93316 36.35578
|
||||
-120.79679 36.21978
|
||||
-120.63636 36.07582
|
||||
-120.52406 35.97185
|
||||
@@ -0,0 +1,10 @@
|
||||
-120.26271 35.71512
|
||||
-120.23380 35.67390
|
||||
-120.19772 35.63300
|
||||
-120.12299 35.56383
|
||||
-120.02674 35.48387
|
||||
-119.98846 35.44344
|
||||
-119.88017 35.32590
|
||||
-119.78610 35.24387
|
||||
-119.67380 35.14792
|
||||
-119.53743 35.04400
|
||||
@@ -0,0 +1,5 @@
|
||||
-120.52406 35.97185
|
||||
-120.43583 35.90791
|
||||
-120.33957 35.81993
|
||||
-120.29568 35.74979
|
||||
-120.26271 35.71512
|
||||
BIN
examples/realcase2_teleseismic_tomography_Thailand/.DS_Store
vendored
Normal file
BIN
examples/realcase2_teleseismic_tomography_Thailand/.DS_Store
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,187 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-50, 550] # depth in km
|
||||
min_max_lat: [10.5, 22.5] # latitude in degree
|
||||
min_max_lon: [95.5, 107.5] # longitude in degree
|
||||
n_rtp: [121, 121, 121] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: 1_src_rec_files/src_rec_file.dat # source receiver file path
|
||||
swap_src_rec: false # swap source and receiver
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_init_N121_121_121.h5 # path to initial model file
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_real # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_source_field: false # True: output the traveltime field and adjoint field of all sources at each iteration. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_kernel: false
|
||||
output_final_model: true # True: output merged final model. This file can be used as the input model for TomoATT. Default: true. File: 'model_final.h5'.
|
||||
output_middle_model: false # True: output merged intermediate models during inversion. This file can be used as the input model for TomoATT. Default: false. File: 'middle_model_step_XXXX.h5'
|
||||
output_in_process: false # True: output at each inv iteration, otherwise, only output step 0, Niter-1, Niter. Default: true. File: 'out_data_sim_group_0'.
|
||||
output_in_process_data: false # True: output src_rec_file at each inv iteration, otherwise, only output step 0, Niter-2, Niter-1. Default: true. File: 'src_rec_file_step_XXXX.dat'
|
||||
single_precision_output: false # True: output results in single precision. Default: false.
|
||||
verbose_output_level: 0 # output internal parameters, (to do)
|
||||
output_file_format: 0 # 0: hdf5, 1: ascii
|
||||
|
||||
# output files:
|
||||
# File: 'out_data_grid.h5'. Keys: ['Mesh']['elem_conn'], element index;
|
||||
# ['Mesh']['node_coords_p'], phi coordinates of nodes;
|
||||
# ['Mesh']['node_coords_t'], theta coordinates of nodes;
|
||||
# ['Mesh']['node_coords_r'], r coordinates of nodes;
|
||||
# ['Mesh']['node_coords_x'], phi coordinates of elements;
|
||||
# ['Mesh']['node_coords_y'], theta coordinates of elements;
|
||||
# ['Mesh']['node_coords_z'], r coordinates of elements;
|
||||
# File: 'out_data_sim_group_0'. Keys: ['model']['vel_inv_XXXX'], velocity model at iteration XXXX;
|
||||
# ['model']['xi_inv_XXXX'], xi model at iteration XXXX;
|
||||
# ['model']['eta_inv_XXXX'], eta model at iteration XXXX
|
||||
# ['model']['Ks_inv_XXXX'], sensitivity kernel related to slowness at iteration XXXX
|
||||
# ['model']['Kxi_inv_XXXX'], sensitivity kernel related to xi at iteration XXXX
|
||||
# ['model']['Keta_inv_XXXX'], sensitivity kernel related to eta at iteration XXXX
|
||||
# ['model']['Ks_density_inv_XXXX'], kernel density of Ks at iteration XXXX
|
||||
# ['model']['Kxi_density_inv_XXXX'], kernel density of Kxi at iteration XXXX
|
||||
# ['model']['Keta_density_inv_XXXX'], kernel density of Keta at iteration XXXX
|
||||
# ['model']['Ks_over_Kden_inv_XXXX'], slowness kernel over kernel density at iteration XXXX
|
||||
# ['model']['Kxi_over_Kden_inv_XXXX'], xi kernel over kernel density at iteration XXXX
|
||||
# ['model']['Keta_over_Kden_inv_XXXX'], eta kernel over kernel density at iteration XXXX
|
||||
# ['model']['Ks_update_inv_XXXX'], slowness kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Kxi_update_inv_XXXX'], xi kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Keta_update_inv_XXXX'], eta kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['1dinv']['vel_1dinv_inv_XXXX'], 2d velocity model at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['r_1dinv'], r coordinates (depth), in 1d inversion mode
|
||||
# ['1dinv']['t_1dinv'], t coordinates (epicenter distance), in 1d inversion mode
|
||||
# File: 'src_rec_file_step_XXXX.dat' or 'src_rec_file_forward.dat'. The synthetic traveltime data file.
|
||||
# File: 'final_model.h5'. Keys: ['eta'], ['xi'], ['vel'], the final model.
|
||||
# File: 'middle_model_step_XXXX.h5'. Keys: ['eta'], ['xi'], ['vel'], the model at step XXXX.
|
||||
# File: 'inversion_grid.txt'. The location of inversion grid nodes
|
||||
# File: 'objective_function.txt'. The objective function value at each iteration
|
||||
# File: 'out_data_sim_group_X'. Keys: ['src_YYYY']['time_field_inv_XXXX'], traveltime field of source YYYY at iteration XXXX;
|
||||
# ['src_YYYY']['adjoint_field_inv_XXXX'], adjoint field of source YYYY at iteration XXXX;
|
||||
# ['1dinv']['time_field_1dinv_YYYY_inv_XXXX'], 2d traveltime field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['adjoint_field_1dinv_YYYY_inv_XXXX'], 2d adjoint field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
# 4 for 1d model inversion
|
||||
run_mode: 1
|
||||
|
||||
have_tele_data: true # An error will be reported if false but source out of study region is used. Default: false.
|
||||
ignore_velocity_discontinuity: true # An error will be reported if false but there is velocity discontinuity (v[ix,iy,iz+1] > v[ix,iy,iz] * 1.2 or v[ix,iy,iz+1] < v[ix,iy,iz] * 0.8) in the input model. Default: false.
|
||||
|
||||
###################################################
|
||||
# model update parameters setting #
|
||||
###################################################
|
||||
model_update:
|
||||
max_iterations: 80 # maximum number of inversion iterations
|
||||
|
||||
step_length: 0.01 # the initial step length of model perturbation. 0.01 means maximum 1% perturbation for each iteration.
|
||||
|
||||
# parameters for optim_method 0 (gradient_descent)
|
||||
optim_method_0:
|
||||
# if step_method:1. if the angle between the current and the previous gradients is greater than step_length_gradient_angle, step size -> step length * step_length_change[0].
|
||||
# otherwise, step size -> step length * step_length_change[1].
|
||||
step_length_gradient_angle: 120 # default: 120.0
|
||||
step_length_change: [0.5, 1.41] # default: [0.5,1.2]
|
||||
Kdensity_coe: 0.3 # default: 0.0, range: 0.0 - 1.0
|
||||
|
||||
# parameters for smooth method 0 (multigrid model parametrization)
|
||||
# inversion grid can be viewed in OUTPUT_FILES/inversion_grid.txt
|
||||
n_inversion_grid: 5 # number of inversion grid sets
|
||||
|
||||
uniform_inv_grid_dep: false # true if use uniform inversion grid for dep, false if use flexible inversion grid
|
||||
uniform_inv_grid_lat: false # true if use uniform inversion grid for lat, false if use flexible inversion grid
|
||||
uniform_inv_grid_lon: false # true if use uniform inversion grid for lon, false if use flexible inversion grid
|
||||
|
||||
# settings for flexible inversion grid
|
||||
dep_inv: [-50, -25, 0, 50, 100, 150, 200, 275, 350, 425, 500, 600,700] # inversion grid for vel in depth (km)
|
||||
lat_inv: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23] # inversion grid for vel in latitude (degree)
|
||||
lon_inv: [95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108] # inversion grid for vel in longitude (degree)
|
||||
trapezoid: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
|
||||
|
||||
# if we want to use another inversion grid for inverting anisotropy, set invgrid_ani: true (default: false)
|
||||
invgrid_ani: false
|
||||
|
||||
# ---------- flexible inversion grid setting for anisotropy ----------
|
||||
# settings for flexible inversion grid for anisotropy
|
||||
dep_inv_ani: [-5, -2, 0, 3, 7, 12, 17, 23, 30, 38, 47, 57] # inversion grid for ani in depth (km)
|
||||
lat_inv_ani: [-2.8, -2.3, -1.8, -1.3, -0.8, -0.3, 0.2, 0.7, 1.2, 1.7, 2.2, 2.7] # inversion grid for ani in latitude (degree)
|
||||
lon_inv_ani: [-1.2, -0.9, -0.6, -0.3, 0, 0.3, 0.6, 0.9, 1.2] # inversion grid for ani in longitude (degree)
|
||||
trapezoid_ani: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
|
||||
|
||||
|
||||
# Carefully change trapezoid and trapezoid_ani, if you really want to use trapezoid inversion grid, increasing the inversion grid spacing with depth to account for the worse data coverage in greater depths.
|
||||
# The trapezoid_ inversion grid with index (i,j,k) in longitude, latitude, and depth is defined as:
|
||||
# if dep_inv[k] < trapezoid[1], lon = lon_inv[i];
|
||||
# lat = lat_inv[j];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[1] <= dep_inv[k] < trapezoid[2], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[2] <= dep_inv[k], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# The shape of trapezoid inversion gird (x) looks like:
|
||||
#
|
||||
# lon_inv[0] [1] [2] [3] [4]
|
||||
# |<-------- (lon_inv[end] - lon_inv[0]) ---->|
|
||||
# dep_inv[0] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[1] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[2] = trapezoid[1] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[3] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[4] = trapezoid[2] / x x x x x \
|
||||
# | |
|
||||
# dep_inv[5] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[6] | x x x x x |
|
||||
# |<---- trapezoid[0]* (lon_inv[end] - lon_inv[0]) ------>|
|
||||
|
||||
# -------------- using absolute traveltime data --------------
|
||||
abs_time:
|
||||
use_abs_time: false # 'true' for using absolute traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- using common source differential traveltime data --------------
|
||||
cs_dif_time:
|
||||
use_cs_time: true # 'true' for using common source differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- using common receiver differential traveltime data --------------
|
||||
cr_dif_time:
|
||||
use_cr_time: false # 'true' for using common receiver differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- inversion parameters --------------
|
||||
update_slowness : true # update slowness (velocity) or not. default: true
|
||||
update_azi_ani : false # update azimuthal anisotropy (xi, eta) or not. default: false
|
||||
|
||||
use_sta_correction: true
|
||||
# initial_sta_correction_file: 4_initial_station_correct/station_correction_file_step_0010.dat # the path of initial station correction
|
||||
step_length_sta_correction: 0.01 # step length relate to the update of station correction terms
|
||||
29
examples/realcase2_teleseismic_tomography_Thailand/README.md
Normal file
29
examples/realcase2_teleseismic_tomography_Thailand/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Real case of teleseismic tomography in Thailand and adjacent areas
|
||||
|
||||
This is a real case to invert common-source differential arrival times for velocity heterogeneity in Thailand and adjacent areas
|
||||
|
||||
Reference:
|
||||
|
||||
[1] J. Chen, S. Wu, M. Xu, M. Nagaso, J. Yao, K. Wang, T. Li, Y. Bai, and P. Tong, Adjoint-state teleseismic traveltime tomography: method and application to Thailand in Indochina Peninsula. J.Geophys. Res. Solid Earth, 128(2023), e2023JB027348.
|
||||
https://doi.org/10.1029/2023JB027348
|
||||
|
||||
[2] J. Chen, M. Nagaso, M. Xu, and P. Tong, TomoATT: An open-source package for Eikonal equation-based adjoint-state traveltime tomography for seismic velocity and azimuthal anisotropy, submitted.
|
||||
https://doi.org/10.48550/arXiv.2412.00031
|
||||
|
||||
Python modules are required to initiate the inversion and to plot final results:
|
||||
- h5py
|
||||
- PyTomoAT
|
||||
- Pygmt
|
||||
- gmt
|
||||
|
||||
Run this example:
|
||||
|
||||
1. Run bash script `bash run_this_example.sh` to execute the test.
|
||||
|
||||
2. After inversion, run `plot_output.py` to plot the results.
|
||||
|
||||
The imaging results:
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -0,0 +1,260 @@
|
||||
# %%
|
||||
import pygmt
|
||||
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
|
||||
|
||||
import os
|
||||
|
||||
# %%
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.data import ATTData
|
||||
import numpy as np
|
||||
|
||||
# %%
|
||||
# read model files
|
||||
|
||||
Ngrid = [121,121,121]
|
||||
data_file = '2_models/model_init_N%d_%d_%d.h5'%(Ngrid[0],Ngrid[1],Ngrid[2])
|
||||
par_file = '3_input_params/input_params_real.yaml'
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
init_model = model.to_xarray()
|
||||
|
||||
data_file = 'OUTPUT_FILES/OUTPUT_FILES_real/final_model.h5'
|
||||
model = ATTModel.read(data_file, par_file)
|
||||
inv_model = model.to_xarray()
|
||||
|
||||
# %%
|
||||
# # read earthquakes and stations
|
||||
|
||||
# from pytomoatt.src_rec import SrcRec
|
||||
|
||||
# # read src_rec_file
|
||||
# sr = SrcRec.read("1_src_rec_files/src_rec_file.dat")
|
||||
|
||||
# # get the coordinates of the stations and earthquakes
|
||||
# stations = sr.receivers[['stlo','stla','stel']].values.T
|
||||
# earthquakes = sr.sources[['evlo','evla','evdp']].values.T
|
||||
|
||||
# print(stations.shape)
|
||||
# print(earthquakes.shape)
|
||||
|
||||
# %%
|
||||
# read earthquakes and stations
|
||||
|
||||
import sys
|
||||
sys.path.append('../utils')
|
||||
import functions_for_data as ffd
|
||||
|
||||
ev, st = ffd.read_src_rec_file('1_src_rec_files/src_rec_file.dat')
|
||||
# earthquake location
|
||||
ev_lon, ev_lat, ev_dep , _ = ffd.data_lon_lat_dep_wt_ev(ev)
|
||||
# station location
|
||||
st_lon, st_lat, _, _ = ffd.data_lon_lat_ele_wt_st(ev,st)
|
||||
|
||||
# %%
|
||||
# load topography
|
||||
region = [97,106,12,21]
|
||||
grid_topo = pygmt.datasets.load_earth_relief(resolution="01m", region=region)
|
||||
grid_gra = pygmt.grdgradient(grid = grid_topo, azimuth = 0)
|
||||
|
||||
# %%
|
||||
def line_read(file):
|
||||
doc=open(file,'r')
|
||||
file = doc.readlines()
|
||||
doc.close()
|
||||
lat = []; lon = [];
|
||||
for info in file:
|
||||
tmp = info.split()
|
||||
lon.append(float(tmp[0]))
|
||||
lat.append(float(tmp[1]))
|
||||
return((lat,lon))
|
||||
|
||||
# %%
|
||||
# plot imgaing results
|
||||
|
||||
fig = pygmt.Figure()
|
||||
try:
|
||||
os.mkdir("img")
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# ------------------ Sub fig 1. topography ------------------
|
||||
region = [97,106,12,21]
|
||||
projection = "B101.5/16.5/12/21/10c"
|
||||
frame = ["xa2+lLongitude", "ya2+lLatitude", "nSWe"]
|
||||
spacing = [0.1, 0.1]
|
||||
|
||||
# topography
|
||||
pygmt.makecpt(cmap="globe", series=[-4000,4000], background = True)
|
||||
fig.grdimage(grid=grid_topo, shading = grid_gra, projection=projection, frame=frame,region=region)
|
||||
|
||||
# station
|
||||
fig.plot(x = st_lon, y = st_lat, style = "t0.4c", fill = "blue", pen = "1p,white", label = "Station")
|
||||
|
||||
|
||||
# tectonic setting
|
||||
(lat,lon) = line_read('tectonics/Khorat_new.txt') # Khorat Plateau
|
||||
fig.plot(x = lon, y = lat, pen = "1p,black")
|
||||
fig.text(text = "Khorat", x = 103.5, y = 17.5, font = "15p,Helvetica-Bold,black", angle = 0)
|
||||
fig.text(text = "Plateau", x = 103.5, y = 16.5, font = "15p,Helvetica-Bold,black", angle = 0)
|
||||
(lat,lon) = line_read('tectonics/WangChaoFault.txt') # Wang-Chao Fault
|
||||
fig.plot(x = lon, y = lat, pen = "1p,black,-")
|
||||
fig.text(text = "WCF", x = 100, y = 16, font = "20p,Helvetica-Bold,white=1p", angle = 315)
|
||||
(lat,lon) = line_read('tectonics/3PagodasFault.txt') # Three Pagodas Fault
|
||||
fig.plot(x = lon, y = lat, pen = "1p,black,-")
|
||||
fig.text(text = "TPF", x = 98.5, y = 14.5, font = "20p,Helvetica-Bold,white=1p", angle = 315)
|
||||
(lat,lon) = line_read('tectonics/DBPF.txt') # Dien Bien Phu Fault
|
||||
fig.plot(x = lon, y = lat, pen = "1p,black,-")
|
||||
fig.text(text = "DBPF", x = 102, y = 19.5, font = "20p,Helvetica-Bold,white=1p", angle = 55)
|
||||
(lat,lon) = line_read('tectonics/SongMaSuture.txt') # Song Ma Suture
|
||||
fig.plot(x = lon, y = lat, pen = "1p,black,-")
|
||||
fig.text(text = "Shan-Thai", x = 99, y = 20, font = "18p,Helvetica-Bold,black=0.5p,white", angle = 0)
|
||||
fig.text(text = "Block", x = 99, y = 19.3, font = "18p,Helvetica-Bold,black=0.5p,white", angle = 0)
|
||||
fig.text(text = "Indochina Block", x = 103.5, y = 15, font = "18p,Helvetica-Bold,black=0.5p,white", angle = 315)
|
||||
|
||||
|
||||
fig.shift_origin(xshift= 1, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a%f"%(4000),"y+lElevation (m)"], position="+w4c/0.3c+h")
|
||||
fig.shift_origin(xshift=-1, yshift=+1.5)
|
||||
|
||||
fig.shift_origin(xshift=0, yshift=-13)
|
||||
|
||||
|
||||
# ------------------ Sub fig 2. earthquakes ------------------
|
||||
|
||||
region = "g"
|
||||
projection = "E101/16/90/10c" # centerlon/centerlat/distnace_range/fig_size
|
||||
frame = ["ya180"]
|
||||
spacing = [0.1, 5]
|
||||
|
||||
fig.basemap(region=region, projection=projection, frame=frame)
|
||||
fig.coast(region=region, projection=projection, frame=frame, water="white", land="gray", A=10000)
|
||||
|
||||
fig.plot(x=101.5, y=16.5, pen="1p,black,-", style="E-60d")
|
||||
fig.plot(x=101.5, y=16.5, pen="1p,black,-", style="E-120d")
|
||||
fig.plot(x=101.5, y=16.5, pen="1p,black,-", style="E-180d")
|
||||
fig.text(x = [101.5, 101.5, 101.5], y = [-8.0, -38.0, -68], text = ['30', '60', '90'], font="13p")
|
||||
|
||||
fig.plot(x=[97,97,106,106,97], y=[11,21,21,11,11], pen="1p,red")
|
||||
pygmt.makecpt(cmap="jet", series=[0, 100], background=True)
|
||||
fig.plot(x = ev_lon, y = ev_lat, size = [0.4]*len(ev_lon), fill = ev_dep, style = "a", cmap = True, pen = "0.5p,white")
|
||||
|
||||
|
||||
fig.shift_origin(xshift= 1, yshift=-1)
|
||||
fig.colorbar(frame = ["a%f"%(50),"y+lFocal depth (km)"], position="+w4c/0.3c+h")
|
||||
fig.shift_origin(xshift=-1, yshift=+1)
|
||||
|
||||
fig.shift_origin(xshift= 13, yshift= 13)
|
||||
|
||||
|
||||
# ------------------ Sub fig 3. depth and vertical profile ------------------
|
||||
|
||||
region = [97,106,12,21]
|
||||
projection = "B101.5/16.5/12/21/10c"
|
||||
frame = ["xa2+lLongitude", "ya2+lLatitude", "nSWe"]
|
||||
spacing = [0.1, 0.1]
|
||||
|
||||
depth_list = [100,200,300,400]
|
||||
start_list = [ [97, 19], [97, 17.2], [101.8, 12] ]
|
||||
end_list = [ [106, 15], [106, 13.2], [101.8, 21] ]
|
||||
|
||||
# depth profiles
|
||||
for idepth, depth in enumerate(depth_list):
|
||||
|
||||
# read models
|
||||
vel_init = init_model.interp_dep(depth, field='vel')
|
||||
vel_inv = inv_model.interp_dep(depth, field='vel')
|
||||
|
||||
if idepth == 3:
|
||||
fig.shift_origin(xshift=-39, yshift=-13)
|
||||
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-2, 2], background=True)
|
||||
x = vel_inv[:,0]; y = vel_inv[:,1]; value = (vel_inv[:,2] - vel_init[:,2])/vel_init[:,2]*100
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
|
||||
fig.grdimage(frame=frame,grid = grid,projection=projection, region=region) # nan_transparent may work
|
||||
|
||||
(lat,lon) = line_read('tectonics/Khorat_new.txt') # Khorat Plateau
|
||||
fig.plot(x = lon, y = lat, pen = "1p,black")
|
||||
|
||||
# vertical profile location
|
||||
fig.plot(x = [start_list[0][0],end_list[0][0]], y = [start_list[0][1],end_list[0][1],], pen = "2p,green,-")
|
||||
fig.text(text = "A", x = start_list[0][0] + 0.5, y = start_list[0][1], font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
|
||||
fig.text(text = "A@+'@+", x = end_list[0][0] - 0.5, y = end_list[0][1] + 0.5, font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
|
||||
|
||||
fig.plot(x = [start_list[1][0],end_list[1][0]], y = [start_list[1][1],end_list[1][1],], pen = "2p,green,-")
|
||||
fig.text(text = "B", x = start_list[1][0] + 0.5, y = start_list[1][1], font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
|
||||
fig.text(text = "B@+'@+", x = end_list[1][0] - 0.5, y = end_list[1][1] + 0.5, font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
|
||||
|
||||
fig.plot(x = [start_list[2][0],end_list[2][0]], y = [start_list[2][1],end_list[2][1],], pen = "2p,green,-")
|
||||
fig.text(text = "C", x = start_list[2][0] - 0.5, y = start_list[2][1] + 0.5, font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
|
||||
fig.text(text = "C@+'@+", x = end_list[2][0] - 0.5, y = end_list[2][1] - 0.5, font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
|
||||
|
||||
# depth label
|
||||
fig.text(text="%d km"%(depth), x = 98 , y = 12.5, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
|
||||
fig.shift_origin(xshift=13)
|
||||
|
||||
fig.shift_origin(yshift=6)
|
||||
|
||||
# vertical profiles
|
||||
for iprof in range(len(start_list)):
|
||||
|
||||
# generate topography data
|
||||
Npoints = 100
|
||||
point_x = np.linspace(start_list[iprof][0],end_list[iprof][0],Npoints)
|
||||
point_y = np.linspace(start_list[iprof][1],end_list[iprof][1],Npoints)
|
||||
points = np.hstack((point_x.reshape(-1,1),point_y.reshape(-1,1)))
|
||||
topo = np.array(pygmt.grdtrack(points=points, grid=grid_topo)[2])
|
||||
topo_dis = [0]
|
||||
for ip in range(1, Npoints):
|
||||
dis = ffd.cal_dis(point_y[0], point_x[0], point_y[ip], point_x[ip])
|
||||
topo_dis.append(dis)
|
||||
topo_dis = np.array(topo_dis)
|
||||
|
||||
# read models
|
||||
vel_init_sec = init_model.interp_sec(start_list[iprof], end_list[iprof], field='vel', val=10)
|
||||
vel_inv_sec = inv_model.interp_sec(start_list[iprof], end_list[iprof], field='vel', val=10)
|
||||
|
||||
|
||||
# plot topography
|
||||
max_dis = np.max(vel_init_sec[:,2])
|
||||
|
||||
region = [0,max_dis,0,2000]
|
||||
projection = "X%f/1c"%(max_dis/400*4)
|
||||
frame = ["ya2000+lElevation (m)", "sW"]
|
||||
|
||||
fig.shift_origin(yshift=4)
|
||||
fig.basemap(region=region, projection=projection, frame=frame)
|
||||
fig.plot(x = topo_dis, y = topo, pen = "1p,black", frame = frame, projection = projection, region = region)
|
||||
fig.shift_origin(yshift=-4)
|
||||
|
||||
# plot model
|
||||
region = [0,max_dis,0,400]
|
||||
projection = "X%f/-4c"%(max_dis/400*4)
|
||||
frame = ["xa300+lDistance (km)", "ya100+lDepth (km)", "nSWe"]
|
||||
spacing = [10, 5]
|
||||
|
||||
x_sec = vel_inv_sec[:,2]; y_sec = vel_inv_sec[:,3]; value_sec = (vel_inv_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4]*100
|
||||
grid = pygmt.surface(x=x_sec, y=y_sec, z=value_sec, spacing=spacing,region=region)
|
||||
fig.grdimage(frame=frame,grid = grid,projection=projection, region=region) # nan_transparent may work
|
||||
|
||||
label_list = ['A', 'B', 'C']
|
||||
fig.text(text = "%s"%(label_list[iprof]), x = 50, y = 50 , font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
|
||||
fig.text(text = "%s@+'@+"%(label_list[iprof]), x = np.max(x) - 50, y = 50, font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
|
||||
|
||||
|
||||
if (iprof == 0):
|
||||
fig.shift_origin(xshift=0, yshift=-6.5)
|
||||
elif (iprof == 1):
|
||||
fig.shift_origin(xshift=13, yshift=6.5)
|
||||
|
||||
fig.shift_origin(xshift= 2, yshift=-2.5)
|
||||
fig.colorbar(frame = ["a%f"%(2),"y+ldlnVp (%)"], position="+w4c/0.3c+h")
|
||||
fig.shift_origin(xshift=-2, yshift=+2.5)
|
||||
|
||||
fig.show()
|
||||
|
||||
fig.savefig("img/imaging_result.png")
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# %%
|
||||
# download src_ref_files from Zenodo
|
||||
import os
|
||||
import requests
|
||||
|
||||
url = 'https://zenodo.org/records/14092478/files/src_rec_file.dat?download=1'
|
||||
|
||||
path = "1_src_rec_files/src_rec_file.dat"
|
||||
|
||||
# check file existence
|
||||
if not os.path.exists(path):
|
||||
try:
|
||||
os.mkdir("1_src_rec_files")
|
||||
except:
|
||||
pass
|
||||
print("Downloading src_rec_file.dat from Zenodo...")
|
||||
response = requests.get(url, stream=True)
|
||||
with open(path, 'wb') as out_file:
|
||||
out_file.write(response.content)
|
||||
print("Download complete.")
|
||||
else:
|
||||
print("src_rec_file.dat already exists.")
|
||||
|
||||
# %%
|
||||
# download initial model from Zenodo
|
||||
|
||||
url = 'https://zenodo.org/records/14092478/files/model_init_N121_121_121.h5?download=1'
|
||||
|
||||
path = "2_models/model_init_N121_121_121.h5"
|
||||
|
||||
# check file existence
|
||||
if not os.path.exists(path):
|
||||
try:
|
||||
os.mkdir("2_models")
|
||||
except:
|
||||
pass
|
||||
print("Downloading model_init_N121_121_121.h5 from Zenodo...")
|
||||
response = requests.get(url, stream=True)
|
||||
with open(path, 'wb') as out_file:
|
||||
out_file.write(response.content)
|
||||
print("Download complete.")
|
||||
else:
|
||||
print("model_init_N121_121_121.h5 already exists.")
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Step 1: Generate necessary input files
|
||||
python prepare_input_files.py
|
||||
|
||||
# Step 2: Run inversion
|
||||
# # for WSL
|
||||
# mpirun -n 8 --allow-run-as-root --oversubscribe ../../build/bin/TOMOATT -i 3_input_params/input_params_real.yaml
|
||||
# for Linux
|
||||
# mpirun -n 8 ../../build/bin/TOMOATT -i 3_input_params/input_params_real.yaml
|
||||
# for conda install
|
||||
mpirun -n 8 TOMOATT -i 3_input_params/input_params_real.yaml
|
||||
|
||||
# # Step 3 (Optional): Plot the results
|
||||
# python plot_output.py
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
97.716435 15.996933
|
||||
97.909999 15.704275
|
||||
98.075912 15.388543
|
||||
98.283303 15.065462
|
||||
98.504520 14.792299
|
||||
98.753389 14.414982
|
||||
99.306431 13.919170
|
||||
99.569126 13.657715
|
||||
99.831821 13.344572
|
||||
@@ -0,0 +1,12 @@
|
||||
100.26019 17.132888
|
||||
100.51411 17.490642
|
||||
100.79624 17.903402
|
||||
101.10658 18.261329
|
||||
101.47335 18.591967
|
||||
101.75549 19.004727
|
||||
102.00940 19.362481
|
||||
102.29154 19.802702
|
||||
102.51724 20.242749
|
||||
102.74295 20.627877
|
||||
102.91223 21.122673
|
||||
103.02508 21.919356
|
||||
@@ -0,0 +1,74 @@
|
||||
101.3217 15.25436
|
||||
101.3610 15.02633
|
||||
101.4085 14.66495
|
||||
101.6319 14.56644
|
||||
101.6012 14.38869
|
||||
101.4514 14.26901
|
||||
101.7127 14.13520
|
||||
101.9088 14.04399
|
||||
102.1729 14.00737
|
||||
102.4503 14.00100
|
||||
102.7636 14.00578
|
||||
103.0485 14.13474
|
||||
103.3082 14.27712
|
||||
103.5336 14.33471
|
||||
103.7845 14.37077
|
||||
103.9997 14.34649
|
||||
104.2485 14.32079
|
||||
104.4734 14.33280
|
||||
104.6885 14.37674
|
||||
104.9102 14.34013
|
||||
105.1688 14.31806
|
||||
105.3968 14.38630
|
||||
105.5182 14.48660
|
||||
105.5693 14.77796
|
||||
105.8248 14.91528
|
||||
106.1238 14.87758
|
||||
106.3348 14.64013
|
||||
106.4688 14.60983
|
||||
106.7040 14.63849
|
||||
106.9841 14.69472
|
||||
107.1072 14.88782
|
||||
106.9818 15.16007
|
||||
106.8467 15.43551
|
||||
106.7018 15.70776
|
||||
106.4761 15.91474
|
||||
106.7336 16.04609
|
||||
106.9007 16.14401
|
||||
106.9118 16.31668
|
||||
106.7038 16.57524
|
||||
106.4385 16.64211
|
||||
106.2010 16.67623
|
||||
106.0120 16.46044
|
||||
105.8274 16.65030
|
||||
105.8194 16.91355
|
||||
105.5656 17.01331
|
||||
105.2865 17.09928
|
||||
104.9742 17.44792
|
||||
104.8155 17.65625
|
||||
104.6904 17.84917
|
||||
104.4882 18.06029
|
||||
104.2648 18.23726
|
||||
104.2338 18.42014
|
||||
104.0404 18.69778
|
||||
103.8294 18.71916
|
||||
103.6035 18.82287
|
||||
103.4194 18.79012
|
||||
103.1891 18.75828
|
||||
102.9576 18.78853
|
||||
102.7519 18.78060
|
||||
102.4620 18.70688
|
||||
102.2884 18.31131
|
||||
102.3415 17.97336
|
||||
102.3233 17.61750
|
||||
102.3959 17.36994
|
||||
102.5198 17.16424
|
||||
102.4485 16.89594
|
||||
102.2198 17.03361
|
||||
102.0690 16.82544
|
||||
101.9004 16.52085
|
||||
101.7902 16.17219
|
||||
101.5551 16.16099
|
||||
101.3962 15.84821
|
||||
101.3255 15.53741
|
||||
101.3217 15.25436
|
||||
@@ -0,0 +1,7 @@
|
||||
103.42006 21.261522
|
||||
103.75862 21.015416
|
||||
104.12539 20.687015
|
||||
104.54859 20.386247
|
||||
104.94357 20.140313
|
||||
105.33856 19.811998
|
||||
105.67712 19.565892
|
||||
@@ -0,0 +1,35 @@
|
||||
97.160627 18.667449
|
||||
97.439913 18.296889
|
||||
97.702608 18.010759
|
||||
97.979130 17.718541
|
||||
98.283303 17.463175
|
||||
98.550606 17.271720
|
||||
98.765678 17.102918
|
||||
99.057562 16.870374
|
||||
99.306431 16.669104
|
||||
99.555300 16.377656
|
||||
99.831821 16.064504
|
||||
100.03921 15.742171
|
||||
100.21895 15.443462
|
||||
100.39869 15.086120
|
||||
100.56460 14.752446
|
||||
100.78582 14.447648
|
||||
100.96556 14.282677
|
||||
101.60156 13.889472
|
||||
101.90573 13.651846
|
||||
102.20990 13.442356
|
||||
102.51408 13.201059
|
||||
102.80719 12.957404
|
||||
103.10972 12.693070
|
||||
103.48190 12.438190
|
||||
103.78607 12.172426
|
||||
104.09025 11.987404
|
||||
104.36677 11.761654
|
||||
104.62946 11.466553
|
||||
104.91981 11.204539
|
||||
105.18250 10.882527
|
||||
105.43137 10.599681
|
||||
105.72172 10.344518
|
||||
106.01207 10.087398
|
||||
106.30241 9.8312565
|
||||
106.50981 9.6872272
|
||||
@@ -0,0 +1,105 @@
|
||||
# %%
|
||||
from pytomoatt.model import ATTModel
|
||||
import os
|
||||
import numpy as np
|
||||
import h5py
|
||||
# %% [markdown]
|
||||
# # Step 1. Generate the ATT model based on the crust1.0 model.
|
||||
|
||||
# %%
|
||||
# generate the .h5 model for TomoATT based on the crust1.0 model. Nearest extrapolation is used.
|
||||
|
||||
param_file = "./3_input_params/input_params_real.yaml"
|
||||
am_crust1p0 = ATTModel(param_file)
|
||||
am_crust1p0.grid_data_crust1(type="vp")
|
||||
|
||||
# %% [markdown]
|
||||
# # Step 2. Generate the ATT model based on ak135 model.
|
||||
|
||||
# %%
|
||||
# Step 2. Generate the ATT model based on ak135 model.
|
||||
|
||||
# ak135.h5 has a three-column dataset 'model'. First column: depth (in km), second column: Vp (in km/s), third column: Vs (in km/s).
|
||||
# a text version of the ak135 model can be found in Kennett et al. (1995):
|
||||
# Kennett, B. L., Engdahl, E. R., & Buland, R. (1995). Constraints on seismic velocities in the Earth from traveltimes. Geophysical Journal International, 122(1), 108-124.
|
||||
|
||||
# Load the 1D ak135 model from the .h5 file.
|
||||
with h5py.File('ak135.h5', 'r') as f:
|
||||
points_ak135 = f['model'][:]
|
||||
|
||||
am_ak135 = ATTModel(param_file)
|
||||
|
||||
# interpolate the 1D ak135 velocity model to the depths of the ATT model.
|
||||
vel_1d = np.interp(am_ak135.depths, points_ak135[:,0], points_ak135[:,1], left=points_ak135[0,1], right=points_ak135[-1,1])
|
||||
|
||||
# Set the 3D velocity model by tiling the 1D velocity model along lat and lon directions.
|
||||
am_ak135.vel = np.tile(vel_1d[:, None, None], (1, am_ak135.n_rtp[1], am_ak135.n_rtp[2]))
|
||||
|
||||
|
||||
# %% [markdown]
|
||||
# # Step 3. Combine ak135 model with crust1.0 model
|
||||
|
||||
# %%
|
||||
# 1. set two depths
|
||||
# if depth < depth_1, vel = crust1p0
|
||||
# if depth_1 <= depth <= depth_2, vel = linear_interp between crust1p0 and ak135
|
||||
# if depth > depth_2, vel = ak135
|
||||
|
||||
am_combined = ATTModel(param_file)
|
||||
|
||||
depth_1 = 35.0
|
||||
depth_2 = 70.0
|
||||
|
||||
ratio = (am_ak135.depths - depth_1) / (depth_2 - depth_1)
|
||||
ratio = np.clip(ratio, 0.0, 1.0)
|
||||
ratio_3d = np.tile(ratio[:, None, None], (1, am_ak135.n_rtp[1], am_ak135.n_rtp[2]))
|
||||
|
||||
# linear interpolation
|
||||
am_combined.vel = am_crust1p0.vel * (1 - ratio_3d) + am_ak135.vel * ratio_3d
|
||||
|
||||
# %% [markdown]
|
||||
# # Step 4. post processing (OPTIONAL)
|
||||
|
||||
# %%
|
||||
am_processed = am_combined.copy()
|
||||
|
||||
# 1. (OPTIONAL) monotonic increase check
|
||||
# Ensure that the velocity model increases monotonically with depth.
|
||||
am_processed.vel[::-1,:,:] = np.maximum.accumulate(am_processed.vel[::-1,:,:], axis=0)
|
||||
|
||||
# 2. (OPTIONAL) Gaussian smoothing to the combined model to avoid sharp discontinuities.
|
||||
## Upgrade PyTomoATT to version 0.2.10 or later to use this function.
|
||||
am_processed.smooth(sigma=am_processed.d_rtp, unit_deg=True, mode='nearest') # standard deviation for Gaussian kernel along each axis (ddep, dlat, dlon)
|
||||
|
||||
|
||||
# %%
|
||||
# output as .h5 file
|
||||
n_rtp = am_processed.n_rtp
|
||||
fname = f"constant_velocity_N{n_rtp[0]:d}_{n_rtp[1]:d}_{n_rtp[2]:d}_PyTomoATT.h5"
|
||||
am_processed.write(fname)
|
||||
|
||||
# %%
|
||||
# visualization of the central lat-lon slice
|
||||
import matplotlib.pyplot as plt
|
||||
dep = am_processed.depths
|
||||
vel = am_processed.vel[:, am_processed.n_rtp[1]//2, am_processed.n_rtp[2]//2]
|
||||
lat = am_processed.latitudes[am_processed.n_rtp[1]//2]
|
||||
lon = am_processed.longitudes[am_processed.n_rtp[2]//2]
|
||||
fig = plt.figure(figsize=(6,6))
|
||||
ax = fig.add_subplot(1,1,1)
|
||||
ax.plot(vel, dep, label='Velocity', color='blue')
|
||||
ax.invert_yaxis()
|
||||
ax.set_xlabel('Vp (km/s)', fontsize=16)
|
||||
ax.set_ylabel('Depth (km)', fontsize=16)
|
||||
ax.tick_params(axis='x', labelsize=16)
|
||||
ax.tick_params(axis='y', labelsize=16)
|
||||
|
||||
ax.set_title(f'Velocity Profile at Lat: {lat:.2f}, Lon: {lon:.2f}', fontsize=16)
|
||||
ax.grid()
|
||||
ax.legend(fontsize=16)
|
||||
plt.show()
|
||||
|
||||
os.makedirs("figs", exist_ok=True)
|
||||
fig.savefig("figs/velocity_profile_lat%.2f_lon%.2f.png"%(lat, lon), facecolor='white', edgecolor='white', bbox_inches='tight')
|
||||
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domain #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-50, 550] # depth in km
|
||||
min_max_lat: [10.5, 22.5] # latitude in degree
|
||||
min_max_lon: [95.5, 107.5] # longitude in degree
|
||||
n_rtp: [121, 121, 121] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: 1_src_rec_files/src_rec_file.dat # source receiver file path
|
||||
swap_src_rec: false # swap source and receiver
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_init_N121_121_121.h5 # path to initial model file
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultaneous runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_real # path to output directory (default is ./OUTPUT_FILES/)
|
||||
output_source_field: false # True: output the traveltime field and adjoint field of all sources at each iteration. Default: false. File: 'out_data_sim_group_X'.
|
||||
output_kernel: false
|
||||
output_final_model: true # True: output merged final model. This file can be used as the input model for TomoATT. Default: true. File: 'model_final.h5'.
|
||||
output_middle_model: false # True: output merged intermediate models during inversion. This file can be used as the input model for TomoATT. Default: false. File: 'middle_model_step_XXXX.h5'
|
||||
output_in_process: false # True: output at each inv iteration, otherwise, only output step 0, Niter-1, Niter. Default: true. File: 'out_data_sim_group_0'.
|
||||
output_in_process_data: false # True: output src_rec_file at each inv iteration, otherwise, only output step 0, Niter-2, Niter-1. Default: true. File: 'src_rec_file_step_XXXX.dat'
|
||||
single_precision_output: false # True: output results in single precision. Default: false.
|
||||
verbose_output_level: 0 # output internal parameters, (to do)
|
||||
output_file_format: 0 # 0: hdf5, 1: ascii
|
||||
|
||||
# output files:
|
||||
# File: 'out_data_grid.h5'. Keys: ['Mesh']['elem_conn'], element index;
|
||||
# ['Mesh']['node_coords_p'], phi coordinates of nodes;
|
||||
# ['Mesh']['node_coords_t'], theta coordinates of nodes;
|
||||
# ['Mesh']['node_coords_r'], r coordinates of nodes;
|
||||
# ['Mesh']['node_coords_x'], phi coordinates of elements;
|
||||
# ['Mesh']['node_coords_y'], theta coordinates of elements;
|
||||
# ['Mesh']['node_coords_z'], r coordinates of elements;
|
||||
# File: 'out_data_sim_group_0'. Keys: ['model']['vel_inv_XXXX'], velocity model at iteration XXXX;
|
||||
# ['model']['xi_inv_XXXX'], xi model at iteration XXXX;
|
||||
# ['model']['eta_inv_XXXX'], eta model at iteration XXXX
|
||||
# ['model']['Ks_inv_XXXX'], sensitivity kernel related to slowness at iteration XXXX
|
||||
# ['model']['Kxi_inv_XXXX'], sensitivity kernel related to xi at iteration XXXX
|
||||
# ['model']['Keta_inv_XXXX'], sensitivity kernel related to eta at iteration XXXX
|
||||
# ['model']['Ks_density_inv_XXXX'], kernel density of Ks at iteration XXXX
|
||||
# ['model']['Kxi_density_inv_XXXX'], kernel density of Kxi at iteration XXXX
|
||||
# ['model']['Keta_density_inv_XXXX'], kernel density of Keta at iteration XXXX
|
||||
# ['model']['Ks_over_Kden_inv_XXXX'], slowness kernel over kernel density at iteration XXXX
|
||||
# ['model']['Kxi_over_Kden_inv_XXXX'], xi kernel over kernel density at iteration XXXX
|
||||
# ['model']['Keta_over_Kden_inv_XXXX'], eta kernel over kernel density at iteration XXXX
|
||||
# ['model']['Ks_update_inv_XXXX'], slowness kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Kxi_update_inv_XXXX'], xi kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['model']['Keta_update_inv_XXXX'], eta kernel over kernel density at iteration XXXX, smoothed by inversion grid
|
||||
# ['1dinv']['vel_1dinv_inv_XXXX'], 2d velocity model at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['r_1dinv'], r coordinates (depth), in 1d inversion mode
|
||||
# ['1dinv']['t_1dinv'], t coordinates (epicenter distance), in 1d inversion mode
|
||||
# File: 'src_rec_file_step_XXXX.dat' or 'src_rec_file_forward.dat'. The synthetic traveltime data file.
|
||||
# File: 'final_model.h5'. Keys: ['eta'], ['xi'], ['vel'], the final model.
|
||||
# File: 'middle_model_step_XXXX.h5'. Keys: ['eta'], ['xi'], ['vel'], the model at step XXXX.
|
||||
# File: 'inversion_grid.txt'. The location of inversion grid nodes
|
||||
# File: 'objective_function.txt'. The objective function value at each iteration
|
||||
# File: 'out_data_sim_group_X'. Keys: ['src_YYYY']['time_field_inv_XXXX'], traveltime field of source YYYY at iteration XXXX;
|
||||
# ['src_YYYY']['adjoint_field_inv_XXXX'], adjoint field of source YYYY at iteration XXXX;
|
||||
# ['1dinv']['time_field_1dinv_YYYY_inv_XXXX'], 2d traveltime field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
# ['1dinv']['adjoint_field_1dinv_YYYY_inv_XXXX'], 2d adjoint field of source YYYY at iteration XXXX, in 1d inversion mode
|
||||
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
# 4 for 1d model inversion
|
||||
run_mode: 1
|
||||
|
||||
have_tele_data: true # An error will be reported if false but source out of study region is used. Default: false.
|
||||
|
||||
###################################################
|
||||
# model update parameters setting #
|
||||
###################################################
|
||||
model_update:
|
||||
max_iterations: 80 # maximum number of inversion iterations
|
||||
|
||||
step_length: 0.01 # the initial step length of model perturbation. 0.01 means maximum 1% perturbation for each iteration.
|
||||
|
||||
# parameters for optim_method 0 (gradient_descent)
|
||||
optim_method_0:
|
||||
# if step_method:1. if the angle between the current and the previous gradients is greater than step_length_gradient_angle, step size -> step length * step_length_change[0].
|
||||
# otherwise, step size -> step length * step_length_change[1].
|
||||
step_length_gradient_angle: 120 # default: 120.0
|
||||
step_length_change: [0.5, 1.41] # default: [0.5,1.2]
|
||||
Kdensity_coe: 0.3 # default: 0.0, range: 0.0 - 1.0
|
||||
|
||||
# parameters for smooth method 0 (multigrid model parametrization)
|
||||
# inversion grid can be viewed in OUTPUT_FILES/inversion_grid.txt
|
||||
n_inversion_grid: 5 # number of inversion grid sets
|
||||
|
||||
uniform_inv_grid_dep: false # true if use uniform inversion grid for dep, false if use flexible inversion grid
|
||||
uniform_inv_grid_lat: false # true if use uniform inversion grid for lat, false if use flexible inversion grid
|
||||
uniform_inv_grid_lon: false # true if use uniform inversion grid for lon, false if use flexible inversion grid
|
||||
|
||||
# settings for flexible inversion grid
|
||||
dep_inv: [-50, -25, 0, 50, 100, 150, 200, 275, 350, 425, 500, 600,700] # inversion grid for vel in depth (km)
|
||||
lat_inv: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23] # inversion grid for vel in latitude (degree)
|
||||
lon_inv: [95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108] # inversion grid for vel in longitude (degree)
|
||||
trapezoid: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
|
||||
|
||||
# if we want to use another inversion grid for inverting anisotropy, set invgrid_ani: true (default: false)
|
||||
invgrid_ani: false
|
||||
|
||||
# ---------- flexible inversion grid setting for anisotropy ----------
|
||||
# settings for flexible inversion grid for anisotropy
|
||||
dep_inv_ani: [-5, -2, 0, 3, 7, 12, 17, 23, 30, 38, 47, 57] # inversion grid for ani in depth (km)
|
||||
lat_inv_ani: [-2.8, -2.3, -1.8, -1.3, -0.8, -0.3, 0.2, 0.7, 1.2, 1.7, 2.2, 2.7] # inversion grid for ani in latitude (degree)
|
||||
lon_inv_ani: [-1.2, -0.9, -0.6, -0.3, 0, 0.3, 0.6, 0.9, 1.2] # inversion grid for ani in longitude (degree)
|
||||
trapezoid_ani: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
|
||||
|
||||
|
||||
# Carefully change trapezoid and trapezoid_ani, if you really want to use trapezoid inversion grid, increasing the inversion grid spacing with depth to account for the worse data coverage in greater depths.
|
||||
# The trapezoid_ inversion grid with index (i,j,k) in longitude, latitude, and depth is defined as:
|
||||
# if dep_inv[k] < trapezoid[1], lon = lon_inv[i];
|
||||
# lat = lat_inv[j];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[1] <= dep_inv[k] < trapezoid[2], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# if trapezoid[2] <= dep_inv[k], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*trapezoid[0];
|
||||
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*trapezoid[0];
|
||||
# dep = dep_inv[k];
|
||||
# The shape of trapezoid inversion gird (x) looks like:
|
||||
#
|
||||
# lon_inv[0] [1] [2] [3] [4]
|
||||
# |<-------- (lon_inv[end] - lon_inv[0]) ---->|
|
||||
# dep_inv[0] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[1] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[2] = trapezoid[1] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[3] / x x x x x \
|
||||
# / \
|
||||
# dep_inv[4] = trapezoid[2] / x x x x x \
|
||||
# | |
|
||||
# dep_inv[5] | x x x x x |
|
||||
# | |
|
||||
# dep_inv[6] | x x x x x |
|
||||
# |<---- trapezoid[0]* (lon_inv[end] - lon_inv[0]) ------>|
|
||||
|
||||
# -------------- using absolute traveltime data --------------
|
||||
abs_time:
|
||||
use_abs_time: false # 'true' for using absolute traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- using common source differential traveltime data --------------
|
||||
cs_dif_time:
|
||||
use_cs_time: true # 'true' for using common source differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- using common receiver differential traveltime data --------------
|
||||
cr_dif_time:
|
||||
use_cr_time: false # 'true' for using common receiver differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
|
||||
|
||||
# -------------- inversion parameters --------------
|
||||
update_slowness : true # update slowness (velocity) or not. default: true
|
||||
update_azi_ani : false # update azimuthal anisotropy (xi, eta) or not. default: false
|
||||
|
||||
use_sta_correction: true
|
||||
# initial_sta_correction_file: 4_initial_station_correct/station_correction_file_step_0010.dat # the path of initial station correction
|
||||
step_length_sta_correction: 0.01 # step length relate to the update of station correction terms
|
||||
BIN
examples/scripts_of_generate_community_model/ak135.h5
Normal file
BIN
examples/scripts_of_generate_community_model/ak135.h5
Normal file
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
# run the script to generate HDF5 model files based on community models
|
||||
# 1. crust1.0 (Laske et al., 2013) + ak135 model (Kennett et al., 1995)
|
||||
python 1_crust1.0_ak135_model.py
|
||||
|
||||
|
||||
# References:
|
||||
# Laske, G., Masters, G., Ma, Z., & Pasyanos, M. (2013, April). Update on CRUST1. 0—A 1-degree global model of Earth’s crust. In Geophysical research abstracts (Vol. 15, No. 15, p. 2658).
|
||||
# Kennett, B. L., Engdahl, E. R., & Buland, R. (1995). Constraints on seismic velocities in the Earth from traveltimes. Geophysical Journal International, 122(1), 108-124.
|
||||
287
examples/scripts_of_generate_hdf5_model/1_generate_models.py
Normal file
287
examples/scripts_of_generate_hdf5_model/1_generate_models.py
Normal file
@@ -0,0 +1,287 @@
|
||||
# %%
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.checkerboard import Checker
|
||||
import os
|
||||
import numpy as np
|
||||
import h5py
|
||||
|
||||
# %% [markdown]
|
||||
# # read YAML parameter file to obtain the grid parameters for the model
|
||||
|
||||
# %%
|
||||
output_path = "models"
|
||||
os.makedirs(output_path, exist_ok=True)
|
||||
|
||||
par_file = "input_params/input_params.yaml"
|
||||
|
||||
att_model = ATTModel(par_file)
|
||||
|
||||
n_rtp = att_model.n_rtp # grid node numbers in r (depth), t (longtitude), p (latitude) directions
|
||||
am_depths = att_model.depths # depths in km
|
||||
am_latitudes = att_model.latitudes # latitudes in degrees
|
||||
am_longitudes = att_model.longitudes # longitudes in degrees
|
||||
|
||||
print("grid node numbers (N_r, N_t, N_p):", n_rtp)
|
||||
print("depths (km):", am_depths)
|
||||
print("latitudes (degree):", am_latitudes)
|
||||
print("longitudes (degree):", am_longitudes)
|
||||
|
||||
# %% [markdown]
|
||||
# # eg1. generate model with constant velocity
|
||||
|
||||
# %%
|
||||
# case 1. ---------- generate a constant velocity model using PyTomoATT module -------------
|
||||
|
||||
# set the velocity model to a constant value
|
||||
constant_v = 6.0 # constant velocity (km/s)
|
||||
att_model.vel[:,:,:] = constant_v
|
||||
att_model.xi[:,:,:] = 0.0
|
||||
att_model.eta[:,:,:] = 0.0
|
||||
|
||||
# write the model to a file
|
||||
fname = "%s/constant_velocity_N%d_%d_%d_PyTomoATT.h5"%(output_path, n_rtp[0], n_rtp[1], n_rtp[2])
|
||||
att_model.write(fname)
|
||||
print("generate model using PyTomoATT:", fname)
|
||||
|
||||
|
||||
# case 2. ---------- generate a constant velocity model using plain loop (h5py module is required) -------------
|
||||
|
||||
# set the velocity model to a constant value
|
||||
vel = np.zeros(n_rtp)
|
||||
xi = np.zeros(n_rtp)
|
||||
eta = np.zeros(n_rtp)
|
||||
for ir in range(n_rtp[0]):
|
||||
for it in range(n_rtp[1]):
|
||||
for ip in range(n_rtp[2]):
|
||||
vel[ir, it, ip] = constant_v
|
||||
|
||||
fname = "%s/constant_velocity_N%d_%d_%d_loop.h5"%(output_path, n_rtp[0], n_rtp[1], n_rtp[2])
|
||||
|
||||
with h5py.File(fname, 'w') as f:
|
||||
f.create_dataset('vel', data=vel)
|
||||
f.create_dataset('xi', data=xi)
|
||||
f.create_dataset('eta', data=eta)
|
||||
print("generate model using plain loop:", fname)
|
||||
|
||||
# %% [markdown]
|
||||
# # eg2. generate a linear velocity model:
|
||||
# vel = 5.0, if depth < 0 km
|
||||
#
|
||||
# vel = 5.0 + 0.1 * depth, if 0 km <= depth <= 30 km
|
||||
#
|
||||
# vel = 8.0, if depth > 30 km
|
||||
|
||||
# %%
|
||||
# case 1. ---------- generate a constant velocity model using PyTomoATT module -------------
|
||||
|
||||
# set the velocity model to a constant value
|
||||
idx = np.where((am_depths >= 0.0) & (am_depths <= 30.0))
|
||||
depth = am_depths[idx]
|
||||
att_model.vel[idx,:,:] = 5.0 + 0.1 * depth[:, np.newaxis, np.newaxis] # velocity increases linearly from 5.0 to 8.0 km/s
|
||||
att_model.vel[np.where(am_depths > 30.0),:,:] = 8.0 # velocity is constant at 8.0 km/s below 30.0 km depth
|
||||
att_model.vel[np.where(am_depths < 0.0),:,:] = 5.0 # velocity is constant at 5.0 km/s above 0.0 km depth
|
||||
|
||||
att_model.xi[:,:,:] = 0.0
|
||||
att_model.eta[:,:,:] = 0.0
|
||||
|
||||
# write the model to a file
|
||||
fname = "%s/linear_velocity_N%d_%d_%d_PyTomoATT.h5"%(output_path, n_rtp[0], n_rtp[1], n_rtp[2])
|
||||
att_model.write(fname)
|
||||
print("generate model using PyTomoATT:", fname)
|
||||
|
||||
# case 2. ---------- generate a linear velocity model using plain loop (h5py module is required) -------------
|
||||
|
||||
# set the velocity model to a linear value
|
||||
vel = np.zeros(n_rtp)
|
||||
xi = np.zeros(n_rtp)
|
||||
eta = np.zeros(n_rtp)
|
||||
|
||||
for ir in range(n_rtp[0]):
|
||||
for it in range(n_rtp[1]):
|
||||
for ip in range(n_rtp[2]):
|
||||
if am_depths[ir] < 0.0:
|
||||
vel[ir, it, ip] = 5.0
|
||||
elif am_depths[ir] <= 30.0:
|
||||
vel[ir, it, ip] = 5.0 + 0.1 * am_depths[ir]
|
||||
else:
|
||||
vel[ir, it, ip] = 8.0
|
||||
fname = "%s/linear_velocity_N%d_%d_%d_loop.h5"%(output_path, n_rtp[0], n_rtp[1], n_rtp[2])
|
||||
|
||||
with h5py.File(fname, 'w') as f:
|
||||
f.create_dataset('vel', data=vel)
|
||||
f.create_dataset('xi', data=xi)
|
||||
f.create_dataset('eta', data=eta)
|
||||
print("generate model using plain loop:", fname)
|
||||
|
||||
# %% [markdown]
|
||||
# # eg3. generate checkerboard model for velocity and anisotropy.
|
||||
#
|
||||
# assign perturbation
|
||||
|
||||
# %%
|
||||
# case 1. ---------- generate a constant velocity model using PyTomoATT module -------------
|
||||
|
||||
# file name of the background model
|
||||
bg_model_fname = "%s/linear_velocity_N%d_%d_%d_PyTomoATT.h5" % (output_path, n_rtp[0], n_rtp[1], n_rtp[2])
|
||||
|
||||
lim_x = [0.5, 1.5] # longitude limits of the checkerboard
|
||||
lim_y = [0.25, 0.75] # latitude limits of the checkerboard
|
||||
lim_z = [0, 30] # depth limits of the checkerboard
|
||||
pert_vel = 0.1 # amplitude of velocity perturbation (%)
|
||||
pert_ani = 0.05 # amplitude of anisotropy perturbation (fraction)
|
||||
ani_dir = 60.0 # fast velocity direction (anti-clockwise from x-axis, in degrees)
|
||||
n_pert_x = 4 # number of checkers in x (lon) direction
|
||||
n_pert_y = 2 # number of checkers in y (lat) direction
|
||||
n_pert_z = 3 # number of checkers in z (dep) direction
|
||||
|
||||
size_x = (lim_x[1] - lim_x[0]) / n_pert_x # size of each checker in x direction
|
||||
size_y = (lim_y[1] - lim_y[0]) / n_pert_y # size of each checker in y direction
|
||||
size_z = (lim_z[1] - lim_z[0]) / n_pert_z # size of each checker in z direction
|
||||
|
||||
|
||||
ckb = Checker(bg_model_fname, para_fname=par_file)
|
||||
# n_pert_x, n_pert_y, n_pert_z: number of checkers in x (lon), y (lat), z (dep) directions
|
||||
# pert_vel: amplitude of velocity perturbation (km/s)
|
||||
# pert_ani: amplitude of anisotropy perturbation (fraction)
|
||||
# ani_dir: fast velicty direction (anti-cloclkwise from x-axis, in degrees)
|
||||
# lim_x, lim_y, lim_z: limits of the checkerboard in x (lon), y (lat), z (dep) directions
|
||||
ckb.checkerboard(
|
||||
n_pert_x=n_pert_x, n_pert_y=n_pert_y, n_pert_z=n_pert_z,
|
||||
pert_vel=pert_vel, pert_ani=pert_ani, ani_dir=ani_dir,
|
||||
lim_x=lim_x, lim_y=lim_y, lim_z=lim_z
|
||||
)
|
||||
|
||||
fname = "%s/linear_velocity_ckb_N%d_%d_%d_PyTomoATT.h5" % (output_path, n_rtp[0], n_rtp[1], n_rtp[2])
|
||||
ckb.write(fname)
|
||||
print("generate checkerboard model based on the linear velocity model using PyTomoATT:", fname)
|
||||
|
||||
# case 2. ---------- generate a checkerboard model using plain loop (h5py module is required) -------------
|
||||
|
||||
# read the background model
|
||||
bg_model = np.zeros(n_rtp)
|
||||
with h5py.File(bg_model_fname, 'r') as f:
|
||||
bg_model = f['vel'][:]
|
||||
|
||||
# set the checkerboard model
|
||||
vel = np.zeros(n_rtp)
|
||||
xi = np.zeros(n_rtp)
|
||||
eta = np.zeros(n_rtp)
|
||||
|
||||
for ir in range(n_rtp[0]):
|
||||
for it in range(n_rtp[1]):
|
||||
for ip in range(n_rtp[2]):
|
||||
depth = am_depths[ir]
|
||||
lat = am_latitudes[it]
|
||||
lon = am_longitudes[ip]
|
||||
|
||||
# check if the current grid node is within the checkerboard limits
|
||||
if (lim_x[0] <= lon <= lim_x[1]) and (lim_y[0] <= lat <= lim_y[1]) and (lim_z[0] <= depth <= lim_z[1]):
|
||||
|
||||
sigma_vel = np.sin(np.pi * (lon - lim_x[0])/size_x) * np.sin(np.pi * (lat - lim_y[0])/size_y) * np.sin(np.pi * (depth - lim_z[0])/size_z)
|
||||
sigma_ani = np.sin(np.pi * (lon - lim_x[0])/size_x) * np.sin(np.pi * (lat - lim_y[0])/size_y) * np.sin(np.pi * (depth - lim_z[0])/size_z)
|
||||
|
||||
if (sigma_ani > 0):
|
||||
psi = ani_dir / 180.0 * np.pi # convert degrees to radians
|
||||
elif (sigma_ani < 0):
|
||||
psi = (ani_dir + 90.0) / 180.0 * np.pi
|
||||
else:
|
||||
psi = 0.0
|
||||
|
||||
else:
|
||||
sigma_vel = 0.0
|
||||
sigma_ani = 0.0
|
||||
psi = 0.0
|
||||
|
||||
# set the velocity and anisotropy
|
||||
vel[ir, it, ip] = bg_model[ir, it, ip] * (1.0 + pert_vel * sigma_vel)
|
||||
xi[ir, it, ip] = pert_ani * abs(sigma_ani) * np.cos(2*psi)
|
||||
eta[ir, it, ip] = pert_ani * abs(sigma_ani) * np.sin(2*psi)
|
||||
|
||||
# write the model to a file
|
||||
fname = "%s/linear_velocity_ckb_N%d_%d_%d_loop.h5" % (output_path, n_rtp[0], n_rtp[1], n_rtp[2])
|
||||
with h5py.File(fname, 'w') as f:
|
||||
f.create_dataset('vel', data=vel)
|
||||
f.create_dataset('xi', data=xi)
|
||||
f.create_dataset('eta', data=eta)
|
||||
print("generate checkerboard model based on the linear velocity model using plain loop:", fname)
|
||||
|
||||
|
||||
# %% [markdown]
|
||||
# # eg4. generate flexible checkerboard model
|
||||
#
|
||||
# the checker size increases with depth;
|
||||
#
|
||||
# the checker size is large for anisotropy;
|
||||
|
||||
# %%
|
||||
# only
|
||||
|
||||
# file name of the background model
|
||||
bg_model_fname = "%s/linear_velocity_N%d_%d_%d_PyTomoATT.h5" % (output_path, n_rtp[0], n_rtp[1], n_rtp[2])
|
||||
|
||||
# read the background model
|
||||
bg_model = np.zeros(n_rtp)
|
||||
with h5py.File(bg_model_fname, 'r') as f:
|
||||
bg_model = f['vel'][:]
|
||||
|
||||
# set the checkerboard model
|
||||
vel = np.zeros(n_rtp)
|
||||
xi = np.zeros(n_rtp)
|
||||
eta = np.zeros(n_rtp)
|
||||
|
||||
for ir in range(n_rtp[0]):
|
||||
for it in range(n_rtp[1]):
|
||||
for ip in range(n_rtp[2]):
|
||||
depth = am_depths[ir]
|
||||
lat = am_latitudes[it]
|
||||
lon = am_longitudes[ip]
|
||||
|
||||
if ((depth >= 0.0) and (depth <= 8.0)):
|
||||
size_vel = 0.2
|
||||
size_ani = 0.3
|
||||
|
||||
sigma_vel = np.sin(np.pi * lon/size_vel) * np.sin(np.pi * lat/size_vel) * np.sin(np.pi * depth/8.0)
|
||||
sigma_ani = np.sin(np.pi * lon/size_ani) * np.sin(np.pi * lat/size_ani) * np.sin(np.pi * depth/8.0)
|
||||
|
||||
elif ((depth > 8.0) and (depth <= 20.0)):
|
||||
|
||||
size_vel = 0.3
|
||||
size_ani = 0.4
|
||||
|
||||
sigma_vel = np.sin(np.pi * lon/size_vel) * np.sin(np.pi * lat/size_vel) * np.sin(np.pi * (depth - 8.0)/12.0 + np.pi)
|
||||
sigma_ani = np.sin(np.pi * lon/size_ani) * np.sin(np.pi * lat/size_ani) * np.sin(np.pi * (depth - 8.0)/12.0 + np.pi)
|
||||
|
||||
elif ((depth > 20.0) and (depth <= 36.0)):
|
||||
|
||||
size_vel = 0.4
|
||||
size_ani = 0.5
|
||||
|
||||
sigma_vel = np.sin(np.pi * lon/size_vel) * np.sin(np.pi * lat/size_vel) * np.sin(np.pi * (depth - 20.0)/16.0 + 2*np.pi)
|
||||
sigma_ani = np.sin(np.pi * lon/size_ani) * np.sin(np.pi * lat/size_ani) * np.sin(np.pi * (depth - 20.0)/16.0 + 2*np.pi)
|
||||
|
||||
else:
|
||||
sigma_vel = 0.0
|
||||
sigma_ani = 0.0
|
||||
|
||||
if (sigma_ani > 0):
|
||||
psi = ani_dir / 180.0 * np.pi # convert degrees to radians
|
||||
elif (sigma_ani < 0):
|
||||
psi = (ani_dir + 90.0) / 180.0 * np.pi
|
||||
else:
|
||||
psi = 0.0
|
||||
|
||||
# set the velocity and anisotropy
|
||||
vel[ir, it, ip] = bg_model[ir, it, ip] * (1.0 + pert_vel * sigma_vel)
|
||||
xi[ir, it, ip] = pert_ani * abs(sigma_ani) * np.cos(2*psi)
|
||||
eta[ir, it, ip] = pert_ani * abs(sigma_ani) * np.sin(2*psi)
|
||||
|
||||
# write the model to a file
|
||||
fname = "%s/linear_velocity_ckb_flex_N%d_%d_%d.h5" % (output_path, n_rtp[0], n_rtp[1], n_rtp[2])
|
||||
with h5py.File(fname, 'w') as f:
|
||||
f.create_dataset('vel', data=vel)
|
||||
f.create_dataset('xi', data=xi)
|
||||
f.create_dataset('eta', data=eta)
|
||||
|
||||
print("generate flexible checkerboard model based on the linear velocity model using plain loop:", fname)
|
||||
|
||||
|
||||
338
examples/scripts_of_generate_hdf5_model/2_plot_models.py
Normal file
338
examples/scripts_of_generate_hdf5_model/2_plot_models.py
Normal file
@@ -0,0 +1,338 @@
|
||||
# %%
|
||||
import pygmt
|
||||
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
|
||||
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.data import ATTData
|
||||
import numpy as np
|
||||
|
||||
|
||||
# %%
|
||||
import os
|
||||
output_path = "figs"
|
||||
os.makedirs(output_path, exist_ok=True)
|
||||
|
||||
|
||||
# %% [markdown]
|
||||
# # eg1. plot constant velocity model
|
||||
|
||||
# %%
|
||||
# ---------------- read model files ----------------
|
||||
# file names
|
||||
# init_model_file = 'models/constant_velocity_N61_51_101_PyTomoATT.h5' # initial model file
|
||||
init_model_file = 'models/constant_velocity_N61_51_101_loop.h5' # initial model file
|
||||
par_file = 'input_params/input_params.yaml' # parameter file
|
||||
|
||||
# read initial and final model file
|
||||
att_model = ATTModel.read(init_model_file, par_file)
|
||||
init_model = att_model.to_xarray()
|
||||
|
||||
# interp vel at depth = 20 km
|
||||
depth = 20.0
|
||||
vel_init = init_model.interp_dep(depth, field='vel') # vel_init[i,:] are (lon, lat, vel)
|
||||
|
||||
# ----------------- pygmt plot ------------------
|
||||
|
||||
fig = pygmt.Figure()
|
||||
pygmt.makecpt(cmap="seis", series=[5, 7], background=True, reverse=False) # colorbar
|
||||
|
||||
|
||||
# ------------ plot horizontal profile of velocity ------------
|
||||
region = [0, 2, 0, 1] # region of interest
|
||||
fig.basemap(region=region, frame=["xa1","ya1","+tVelocity (km/s)"], projection="M10c") # base map
|
||||
|
||||
depth = 20.0
|
||||
prof_init = init_model.interp_dep(depth, field='vel') # prof_init[i,:] are (lon, lat, vel)
|
||||
lon = prof_init[:,0] # longitude
|
||||
lat = prof_init[:,1] # latitude
|
||||
vel = prof_init[:,2] # velocity
|
||||
|
||||
grid = pygmt.surface(x=lon, y=lat, z=vel, spacing=0.04,region=region)
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
fig.text(text="%d km"%(depth), x = 0.2 , y = 0.1, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a1","y+lVp (km/s)"], position="+e+w4c/0.3c+h")
|
||||
fig.shift_origin(xshift=0, yshift= 1.5)
|
||||
|
||||
# ------------ plot horivertical profile of velocity ------------
|
||||
fig.shift_origin(xshift=11, yshift= 0)
|
||||
|
||||
region = [0, 40, 0, 1] # region of interest
|
||||
fig.basemap(region=region, frame=["xa20+lDepth (km)","ya1+lLatitude","nSwE"], projection="X3c/5c") # base map
|
||||
|
||||
start = [1,0]; end = [1,1]; gap = 1
|
||||
prof_init = init_model.interp_sec(start, end, field='vel', val = gap) # prof_init[i,:] are (lon, lat, dis, dep, vel)
|
||||
lat = prof_init[:,1] # lat
|
||||
dep = prof_init[:,3] # depth
|
||||
vel = prof_init[:,4] # velocity
|
||||
|
||||
grid = pygmt.surface(x=dep, y=lat, z=vel, spacing="1/0.04",region=region)
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
|
||||
fig.savefig("figs/constant_velocity.png") # save figure
|
||||
fig.show()
|
||||
|
||||
|
||||
|
||||
# %% [markdown]
|
||||
# # eg2. plot linear velocity model
|
||||
|
||||
# %%
|
||||
# ---------------- read model files ----------------
|
||||
# file names
|
||||
# init_model_file = 'models/linear_velocity_N61_51_101_PyTomoATT.h5' # initial model file
|
||||
init_model_file = 'models/linear_velocity_N61_51_101_loop.h5' # initial model file
|
||||
par_file = 'input_params/input_params.yaml' # parameter file
|
||||
|
||||
# read initial and final model file
|
||||
att_model = ATTModel.read(init_model_file, par_file)
|
||||
init_model = att_model.to_xarray()
|
||||
|
||||
# # interp vel at depth = 20 km
|
||||
# depth = 20.0
|
||||
# vel_init = init_model.interp_dep(depth, field='vel') # vel_init[i,:] are (lon, lat, vel)
|
||||
|
||||
# ----------------- pygmt plot ------------------
|
||||
|
||||
fig = pygmt.Figure()
|
||||
pygmt.makecpt(cmap="seis", series=[5, 8], background=True, reverse=False) # colorbar
|
||||
|
||||
|
||||
# ------------ plot horizontal profile of velocity ------------
|
||||
region = [0, 2, 0, 1] # region of interest
|
||||
fig.basemap(region=region, frame=["xa1","ya1","+tVelocity (km/s)"], projection="M10c") # base map
|
||||
|
||||
depth = 20.0
|
||||
prof_init = init_model.interp_dep(depth, field='vel') # prof_init[i,:] are (lon, lat, vel)
|
||||
lon = prof_init[:,0] # longitude
|
||||
lat = prof_init[:,1] # latitude
|
||||
vel = prof_init[:,2] # velocity
|
||||
|
||||
grid = pygmt.surface(x=lon, y=lat, z=vel, spacing=0.04,region=region)
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
fig.text(text="%d km"%(depth), x = 0.2 , y = 0.1, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a1","y+lVp (km/s)"], position="+e+w4c/0.3c+h")
|
||||
fig.shift_origin(xshift=0, yshift= 1.5)
|
||||
|
||||
# ------------ plot horivertical profile of velocity ------------
|
||||
fig.shift_origin(xshift=11, yshift= 0)
|
||||
|
||||
region = [0, 40, 0, 1] # region of interest
|
||||
fig.basemap(region=region, frame=["xa20+lDepth (km)","ya1+lLatitude","nSwE"], projection="X3c/5c") # base map
|
||||
|
||||
start = [1,0]; end = [1,1]; gap = 1
|
||||
prof_init = init_model.interp_sec(start, end, field='vel', val = gap) # prof_init[i,:] are (lon, lat, dis, dep, vel)
|
||||
lat = prof_init[:,1] # lat
|
||||
dep = prof_init[:,3] # depth
|
||||
vel = prof_init[:,4] # velocity
|
||||
|
||||
grid = pygmt.surface(x=dep, y=lat, z=vel, spacing="1/0.04",region=region)
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
|
||||
fig.savefig("figs/linear_velocity.png") # save figure
|
||||
fig.show()
|
||||
|
||||
|
||||
|
||||
# %% [markdown]
|
||||
# # eg3. plot checkerboard model
|
||||
|
||||
# %%
|
||||
# ---------------- read model files ----------------
|
||||
# file names
|
||||
init_model_file = 'models/linear_velocity_N61_51_101_PyTomoATT.h5' # initial model file
|
||||
ckb_model_file = 'models/linear_velocity_ckb_N61_51_101_PyTomoATT.h5' # checkerboard model file
|
||||
# ckb_model_file = 'models/linear_velocity_ckb_N61_51_101_loop.h5' # checkerboard model file
|
||||
par_file = 'input_params/input_params.yaml' # parameter file
|
||||
|
||||
# read initial and final model file
|
||||
att_model = ATTModel.read(init_model_file, par_file)
|
||||
init_model = att_model.to_xarray()
|
||||
|
||||
att_model = ATTModel.read(ckb_model_file, par_file)
|
||||
ckb_model = att_model.to_xarray()
|
||||
|
||||
# # interp vel at depth = 20 km
|
||||
# depth = 20.0
|
||||
# vel_init = init_model.interp_dep(depth, field='vel') # vel_init[i,:] are (lon, lat, vel)
|
||||
# vel_ckb = ckb_model.interp_dep(depth, field='vel') # vel_ckb[i,:] are (lon, lat, vel)
|
||||
|
||||
# ----------------- pygmt plot ------------------
|
||||
|
||||
fig = pygmt.Figure()
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-10,10], background=True, reverse=False) # colorbar
|
||||
|
||||
|
||||
# ------------ plot horizontal profile of velocity ------------
|
||||
region = [0, 2, 0, 1] # region of interest
|
||||
fig.basemap(region=region, frame=["xa1","ya1","+tVelocity perturbation (%)"], projection="M10c") # base map
|
||||
|
||||
# velocity perturbation at depth = 15 km
|
||||
depth = 15.0
|
||||
prof_init = init_model.interp_dep(depth, field='vel') # prof_init[i,:] are (lon, lat, vel)
|
||||
prof_ckb = ckb_model.interp_dep(depth, field='vel') # prof_ckb[i,:] are (lon, lat, vel)
|
||||
lon = prof_init[:,0] # longitude
|
||||
lat = prof_init[:,1] # latitude
|
||||
vel_pert = (prof_ckb[:,2] - prof_init[:,2])/prof_init[:,2] * 100 # velocity perturbation related to initial model
|
||||
|
||||
grid = pygmt.surface(x=lon, y=lat, z=vel_pert, spacing=0.01,region=region)
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
fig.text(text="%d km"%(depth), x = 0.2 , y = 0.1, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# fast velocity directions (FVDs)
|
||||
samp_interval = 3 # control the density of anisotropic arrows
|
||||
width = 0.06 # width of the anisotropic arrow
|
||||
ani_per_1 = 0.01; ani_per_2 = 0.05; scale = 0.5; basic = 0.1 # control the length of anisotropic arrows related to the amplitude of anisotropy. length = 0.1 + (amplitude - ani_per_1) / (ani_per_2 - ani_per_1) * scale
|
||||
ani_thd = ani_per_1 # if the amplitude of anisotropy is smaller than ani_thd, no anisotropic arrow will be plotted
|
||||
|
||||
phi = ckb_model.interp_dep(depth, field='phi', samp_interval=samp_interval) # phi_inv[i,:] are (lon, lat, phi)
|
||||
epsilon = ckb_model.interp_dep(depth, field='epsilon', samp_interval=samp_interval) # epsilon_inv[i,:] are (lon, lat, epsilon)
|
||||
ani_lon = phi[:,0].reshape(-1,1)
|
||||
ani_lat = phi[:,1].reshape(-1,1)
|
||||
ani_phi = phi[:,2].reshape(-1,1)
|
||||
length = ((epsilon[:,2] - ani_per_1) / (ani_per_2 - ani_per_1) * scale + basic).reshape(-1,1)
|
||||
ani_arrow = np.hstack([ani_lon, ani_lat, ani_phi, length, np.ones((ani_lon.size,1))*width]) # lon, lat, color, angle[-90,90], length, width
|
||||
|
||||
# remove arrows with small amplitude of anisotropy
|
||||
idx = np.where(epsilon[:,2] > ani_thd)[0] # indices of arrows with large enough amplitude of anisotropy
|
||||
ani_arrow = ani_arrow[idx,:] # remove arrows with small amplitude of anisotropy
|
||||
|
||||
# plot anisotropic arrows
|
||||
fig.plot(ani_arrow, style='j', fill='yellow1', pen='0.5p,black') # plot fast velocity direction
|
||||
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a10","y+ldlnVp (%)"], position="+e+w4c/0.3c+h")
|
||||
fig.shift_origin(xshift=0, yshift= 1.5)
|
||||
|
||||
# ------------ plot horivertical profile of velocity ------------
|
||||
fig.shift_origin(xshift=11, yshift= 0)
|
||||
|
||||
region = [0, 40, 0, 1] # region of interest
|
||||
fig.basemap(region=region, frame=["xa20+lDepth (km)","ya1+lLatitude","nSwE"], projection="X3c/5c") # base map
|
||||
|
||||
start = [0.875,0]; end = [0.875,1]; gap = 1
|
||||
prof_init = init_model.interp_sec(start, end, field='vel', val = gap) # prof_init[i,:] are (lon, lat, dis, dep, vel)
|
||||
prof_ckb = ckb_model.interp_sec(start, end, field='vel', val = gap) # prof_ckb[i,:] are (lon, lat, dis, dep, vel)
|
||||
lat = prof_init[:,1] # lat
|
||||
dep = prof_init[:,3] # depth
|
||||
vel = (prof_ckb[:,4] - prof_init[:,4])/prof_init[:,4] * 100 # velocity perturbation related to initial model
|
||||
|
||||
grid = pygmt.surface(x=dep, y=lat, z=vel, spacing="1/0.01",region=region)
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
|
||||
fig.savefig("figs/checkerboard_velocity.png") # save figure
|
||||
fig.show()
|
||||
|
||||
|
||||
# %% [markdown]
|
||||
# # eg4. plot flexible checkerboard model
|
||||
|
||||
# %%
|
||||
# ---------------- read model files ----------------
|
||||
# file names
|
||||
init_model_file = 'models/linear_velocity_N61_51_101_PyTomoATT.h5' # initial model file
|
||||
ckb_model_file = 'models/linear_velocity_ckb_flex_N61_51_101.h5' # checkerboard model file
|
||||
par_file = 'input_params/input_params.yaml' # parameter file
|
||||
|
||||
# read initial and final model file
|
||||
att_model = ATTModel.read(init_model_file, par_file)
|
||||
init_model = att_model.to_xarray()
|
||||
|
||||
att_model = ATTModel.read(ckb_model_file, par_file)
|
||||
ckb_model = att_model.to_xarray()
|
||||
|
||||
# # interp vel at depth = 20 km
|
||||
# depth = 20.0
|
||||
# vel_init = init_model.interp_dep(depth, field='vel') # vel_init[i,:] are (lon, lat, vel)
|
||||
# vel_ckb = ckb_model.interp_dep(depth, field='vel') # vel_ckb[i,:] are (lon, lat, vel)
|
||||
|
||||
# ----------------- pygmt plot ------------------
|
||||
|
||||
fig = pygmt.Figure()
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-10,10], background=True, reverse=False) # colorbar
|
||||
|
||||
|
||||
for depth in [4,14,28]:
|
||||
# ------------ plot horizontal profile of velocity ------------
|
||||
region = [0, 2, 0, 1] # region of interest
|
||||
fig.basemap(region=region, frame=["xa1","ya1","NsEw"], projection="M10c") # base map
|
||||
|
||||
# velocity perturbation at depth = 15 km
|
||||
prof_init = init_model.interp_dep(depth, field='vel') # prof_init[i,:] are (lon, lat, vel)
|
||||
prof_ckb = ckb_model.interp_dep(depth, field='vel') # prof_ckb[i,:] are (lon, lat, vel)
|
||||
lon = prof_init[:,0] # longitude
|
||||
lat = prof_init[:,1] # latitude
|
||||
vel_pert = (prof_ckb[:,2] - prof_init[:,2])/prof_init[:,2] * 100 # velocity perturbation related to initial model
|
||||
|
||||
grid = pygmt.surface(x=lon, y=lat, z=vel_pert, spacing=0.01,region=region)
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
|
||||
# fast velocity directions (FVDs)
|
||||
samp_interval = 3 # control the density of anisotropic arrows
|
||||
width = 0.06 # width of the anisotropic arrow
|
||||
ani_per_1 = 0.01; ani_per_2 = 0.05; scale = 0.5; basic = 0.1 # control the length of anisotropic arrows related to the amplitude of anisotropy. length = 0.1 + (amplitude - ani_per_1) / (ani_per_2 - ani_per_1) * scale
|
||||
ani_thd = ani_per_1 # if the amplitude of anisotropy is smaller than ani_thd, no anisotropic arrow will be plotted
|
||||
|
||||
phi = ckb_model.interp_dep(depth, field='phi', samp_interval=samp_interval) # phi_inv[i,:] are (lon, lat, phi)
|
||||
epsilon = ckb_model.interp_dep(depth, field='epsilon', samp_interval=samp_interval) # epsilon_inv[i,:] are (lon, lat, epsilon)
|
||||
ani_lon = phi[:,0].reshape(-1,1)
|
||||
ani_lat = phi[:,1].reshape(-1,1)
|
||||
ani_phi = phi[:,2].reshape(-1,1)
|
||||
length = ((epsilon[:,2] - ani_per_1) / (ani_per_2 - ani_per_1) * scale + basic).reshape(-1,1)
|
||||
ani_arrow = np.hstack([ani_lon, ani_lat, ani_phi, length, np.ones((ani_lon.size,1))*width]) # lon, lat, color, angle[-90,90], length, width
|
||||
|
||||
# remove arrows with small amplitude of anisotropy
|
||||
idx = np.where(epsilon[:,2] > ani_thd)[0] # indices of arrows with large enough amplitude of anisotropy
|
||||
ani_arrow = ani_arrow[idx,:] # remove arrows with small amplitude of anisotropy
|
||||
|
||||
# plot anisotropic arrows
|
||||
fig.plot(ani_arrow, style='j', fill='yellow1', pen='0.5p,black') # plot fast velocity direction
|
||||
|
||||
fig.text(text="%d km"%(depth), x = 0.2 , y = 0.1, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# plot vertical profile
|
||||
fig.plot(x=[0.9, 0.9], y=[0, 1], pen="2p,black,-") # vertical line
|
||||
|
||||
fig.shift_origin(xshift=0, yshift=-6)
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift= 4.5)
|
||||
fig.colorbar(frame = ["a10","y+ldlnVp (%)"], position="+e+w4c/0.3c+h")
|
||||
fig.shift_origin(xshift=0, yshift= 1.5)
|
||||
|
||||
# ------------ plot horivertical profile of velocity ------------
|
||||
fig.shift_origin(xshift=11, yshift= 0)
|
||||
|
||||
region = [0, 40, 0, 1] # region of interest
|
||||
fig.basemap(region=region, frame=["xa20+lDepth (km)","ya1+lLatitude","nSwE"], projection="X3c/5c") # base map
|
||||
|
||||
start = [0.9,0]; end = [0.9,1]; gap = 1
|
||||
prof_init = init_model.interp_sec(start, end, field='vel', val = gap) # prof_init[i,:] are (lon, lat, dis, dep, vel)
|
||||
prof_ckb = ckb_model.interp_sec(start, end, field='vel', val = gap) # prof_ckb[i,:] are (lon, lat, dis, dep, vel)
|
||||
lat = prof_init[:,1] # lat
|
||||
dep = prof_init[:,3] # depth
|
||||
vel = (prof_ckb[:,4] - prof_init[:,4])/prof_init[:,4] * 100 # velocity perturbation related to initial model
|
||||
|
||||
grid = pygmt.surface(x=dep, y=lat, z=vel, spacing="1/0.01",region=region)
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
|
||||
fig.savefig("figs/flexible_checkerboard_velocity.png") # save figure
|
||||
fig.show()
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
version: 3
|
||||
|
||||
#################################################
|
||||
# computational domian #
|
||||
#################################################
|
||||
domain:
|
||||
min_max_dep: [-10, 50] # depth in km
|
||||
min_max_lat: [0, 1] # latitude in degree
|
||||
min_max_lon: [0, 2] # longitude in degree
|
||||
n_rtp: [61, 51, 101] # number of nodes in depth,latitude,longitude direction
|
||||
|
||||
#################################################
|
||||
# traveltime data file path #
|
||||
#################################################
|
||||
source:
|
||||
src_rec_file: 1_src_rec_files/src_rec_config.dat # source receiver file path
|
||||
swap_src_rec: true # swap source and receiver
|
||||
|
||||
#################################################
|
||||
# initial model file path #
|
||||
#################################################
|
||||
model:
|
||||
init_model_path: 2_models/model_ckb_N61_51_101.h5 # path to initial model file
|
||||
|
||||
#################################################
|
||||
# parallel computation settings #
|
||||
#################################################
|
||||
parallel: # parameters for parallel computation
|
||||
n_sims: 8 # number of simultanoues runs (parallel the sources)
|
||||
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
|
||||
|
||||
############################################
|
||||
# output file setting #
|
||||
############################################
|
||||
output_setting:
|
||||
output_dir: OUTPUT_FILES/OUTPUT_FILES_signal # path to output director (default is ./OUTPUT_FILES/)
|
||||
output_final_model: true # output merged final model (final_model.h5) or not.
|
||||
output_in_process: false # output model at each inv iteration or not.
|
||||
output_in_process_data: false # output src_rec_file at each inv iteration or not.
|
||||
output_file_format: 0
|
||||
|
||||
#################################################
|
||||
# inversion or forward modeling #
|
||||
#################################################
|
||||
# run mode
|
||||
# 0 for forward simulation only,
|
||||
# 1 for inversion
|
||||
# 2 for earthquake relocation
|
||||
# 3 for inversion + earthquake relocation
|
||||
run_mode: 0
|
||||
13
examples/scripts_of_generate_hdf5_model/run_this_example.sh
Normal file
13
examples/scripts_of_generate_hdf5_model/run_this_example.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
#!/bin/bash
|
||||
|
||||
# run the script to generate HDF5 model files for TomoATT. Four models will be generated for TomoATT
|
||||
# 1. constant velocity model
|
||||
# 2. linear velocity model
|
||||
# 3. regular checkerboard model based on the linear velocity model
|
||||
# 4. flexible checkerboard model based on the linear velocity model
|
||||
|
||||
python 1_generate_models.py
|
||||
|
||||
# run the script to plot the generated models (optional)
|
||||
|
||||
python 2_plot_models.py
|
||||
173
examples/scripts_of_plotting/1_plot_model.py
Normal file
173
examples/scripts_of_plotting/1_plot_model.py
Normal file
@@ -0,0 +1,173 @@
|
||||
# %%
|
||||
import pygmt
|
||||
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
|
||||
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.data import ATTData
|
||||
import numpy as np
|
||||
|
||||
# %%
|
||||
# (Option 1) plot the final model after inversion
|
||||
|
||||
# Need to set "output_final_model" as "True" in the input_params.yaml file
|
||||
|
||||
# ---------------- read model files ----------------
|
||||
# file names
|
||||
init_model_file = 'input_files/model_init_N61_61_61.h5' # initial model file
|
||||
inv_model_file = 'OUTPUT_FILES/final_model.h5' # final model file
|
||||
par_file = 'input_files/input_params.yaml' # parameter file
|
||||
|
||||
# read initial and final model file
|
||||
model = ATTModel.read(init_model_file, par_file)
|
||||
init_model = model.to_xarray()
|
||||
|
||||
model = ATTModel.read(inv_model_file, par_file)
|
||||
inv_model = model.to_xarray()
|
||||
|
||||
|
||||
# %%
|
||||
# # (Option 2) plot the model at the XX iteration
|
||||
|
||||
# # Need to set "output_middle_model" as "True" in the input_params.yaml file
|
||||
|
||||
# # ---------------- read model files ----------------
|
||||
# # file names
|
||||
# init_model_file = 'input_files/model_init_N61_61_61.h5' # initial model file
|
||||
# inv_model_file = 'OUTPUT_FILES/middle_model_step_0007.h5' # final model file
|
||||
# par_file = 'input_files/input_params.yaml' # parameter file
|
||||
|
||||
# # read initial and final model file
|
||||
# model = ATTModel.read(init_model_file, par_file)
|
||||
# init_model = model.to_xarray()
|
||||
|
||||
# model = ATTModel.read(inv_model_file, par_file)
|
||||
# inv_model = model.to_xarray()
|
||||
|
||||
# %%
|
||||
import os
|
||||
try:
|
||||
os.mkdir('img')
|
||||
except:
|
||||
pass
|
||||
|
||||
# %%
|
||||
# ---------------- access 3D model parameters ----------------
|
||||
|
||||
# we can access 3D dataset with keys:
|
||||
# 1. "vel" for velocity
|
||||
# 2. "phi" fast velocity direction, anti-clock angle w.r.t the east direction. (only available for anisotropic model)
|
||||
# 3. "epsilon" for anisotropic magnitude (only available for anisotropic model)
|
||||
# 4. "xi" and "eta" for anisotropic parameters: xi = epsilon * cos(phi), eta = epsilon * sin(phi)
|
||||
vel_3d_array = inv_model["vel"]
|
||||
phi_3d_array = inv_model["phi"]
|
||||
epsilon_3d_array = inv_model["epsilon"]
|
||||
xi_3d_array = inv_model["xi"]
|
||||
eta_3d_array = inv_model["eta"]
|
||||
|
||||
print("3D array of model parameters. \n vel: ", vel_3d_array.shape, " \n phi: ", phi_3d_array.shape,
|
||||
" \n epsilon: ", epsilon_3d_array.shape, " \n xi: ", xi_3d_array.shape, " \n eta: ", eta_3d_array.shape)
|
||||
|
||||
# %%
|
||||
# ---------------- 2D depth profile of velocity perturbation ----------------
|
||||
|
||||
# interp vel at depth = 20 km
|
||||
depth = 20.0
|
||||
vel_init = init_model.interp_dep(depth, field='vel') # vel_init[i,:] are (lon, lat, vel)
|
||||
vel_inv = inv_model.interp_dep(depth, field='vel')
|
||||
|
||||
print("vel_depth at depth = ", depth, " km. vel_depth:", vel_init.shape, ", (lon, lat, vel)")
|
||||
|
||||
# plot
|
||||
fig = pygmt.Figure()
|
||||
fig.basemap(region=[0,2,0,2], frame=["xa1","ya1","+tVelocity perturbation"], projection="M10c") # base map
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-20, 20], background=True, reverse=False) # colorbar
|
||||
|
||||
x = vel_init[:,0]; # longitude
|
||||
y = vel_init[:,1]; # latitude
|
||||
value = (vel_inv[:,2] - vel_init[:,2])/vel_init[:,2] * 100 # velocity perturbation relative to the initial model
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=0.04,region=[0,2,0,2])
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
fig.text(text="%d km"%(depth), x = 0.2 , y = 0.1, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a20","y+ldlnVp (%)"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.savefig("img/1_dep_vel.png")
|
||||
|
||||
# %%
|
||||
# ---------------- 2D depth profile of azimuthal anisotropy ----------------
|
||||
|
||||
# interp magnitude of anisotropy at depth = 20 km
|
||||
depth = 20.0
|
||||
epsilon_inv = inv_model.interp_dep(depth, field='epsilon') # epsilon_inv[i,:] are (lon, lat, epsilon)
|
||||
|
||||
print("epsilon_inv at depth = ", depth, " km. epsilon_inv:", epsilon_inv.shape, ", (lon, lat, epsilon)")
|
||||
|
||||
# generate fast velocity direction (anisotropic arrow)
|
||||
samp_interval = 3
|
||||
length = 10
|
||||
width = 0.1
|
||||
ani_thd = 0.02
|
||||
ani_phi = inv_model.interp_dep(depth, field='phi', samp_interval=samp_interval)
|
||||
ani_epsilon = inv_model.interp_dep(depth, field='epsilon', samp_interval=samp_interval)
|
||||
ani_arrow = np.hstack([ani_phi, ani_epsilon[:,2].reshape(-1, 1)*length, np.ones((ani_epsilon.shape[0],1))*width]) # lon, lat, angle, length, width
|
||||
idx = np.where(ani_epsilon[:,2] > ani_thd)
|
||||
ani_arrow = ani_arrow[idx[0],:]
|
||||
|
||||
print("ani_arrow at depth = ", depth, " km. ani_arrow:", ani_arrow.shape, ", (lon, lat, angle, length, width)")
|
||||
|
||||
|
||||
# plot
|
||||
fig = pygmt.Figure()
|
||||
fig.basemap(region=[0,2,0,2], frame=["xa1","ya1","+tAzimuthal Anisotropy"], projection="M10c") # base map
|
||||
pygmt.makecpt(cmap="cool", series=[0, 0.1], background=True, reverse=False) # colorbar
|
||||
|
||||
x = epsilon_inv[:,0]; # longitude
|
||||
y = epsilon_inv[:,1]; # latitude
|
||||
value = epsilon_inv[:,2] # magnitude of anisotropy
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=0.04,region=[0,2,0,2])
|
||||
|
||||
fig.grdimage(grid = grid) # plot magnitude of anisotropy
|
||||
fig.plot(ani_arrow, style='j', fill='yellow1', pen='0.5p,black') # plot fast velocity direction
|
||||
|
||||
fig.text(text="%d km"%(depth), x = 0.2 , y = 0.1, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a0.1","y+lAnisotropy"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.savefig("img/1_dep_ani.png")
|
||||
|
||||
# %%
|
||||
# ---------------- 2D vertical profile of velocity perturbation ----------------
|
||||
|
||||
# interp vel from [0,0.75] in lon-lat to [2,0.75] in lon-lat, gap = 1 km
|
||||
start = [0,0.75]; end = [2,0.75]; gap = 1
|
||||
vel_init_sec = init_model.interp_sec(start, end, field='vel', val = gap) # vel_init_sec[i,:] are (lon, lat, dis, dep, vel)
|
||||
vel_inv_sec = inv_model.interp_sec(start, end, field='vel', val = gap)
|
||||
|
||||
print("vel_init_sec:", vel_init_sec.shape, ", (lon, lat, distance, depth, vel)")
|
||||
|
||||
# plot
|
||||
fig = pygmt.Figure()
|
||||
fig.basemap(region=[0,2,0,40], frame=["xa1+lLongitude","ya20+lDepth (km)","+tVelocity perturbation"], projection="X10c/-4c") # base map
|
||||
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-20, 20], background=True, reverse=False) # colorbar
|
||||
|
||||
x = vel_init_sec[:,0]; # longitude
|
||||
y = vel_init_sec[:,3]; # depth
|
||||
value = (vel_inv_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4] * 100 # velocity perturbation relative to the initial model
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="0.04/1",region=[0,2,0,40])
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
fig.text(text="A", x = 0.1 , y = 5, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
fig.text(text="A@+'@+", x = 1.9 , y = 5, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-2)
|
||||
fig.colorbar(frame = ["a20","y+ldlnVp (%)"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.savefig("img/1_sec_vel.png")
|
||||
|
||||
|
||||
187
examples/scripts_of_plotting/2_plot_time_field.py
Normal file
187
examples/scripts_of_plotting/2_plot_time_field.py
Normal file
@@ -0,0 +1,187 @@
|
||||
# %%
|
||||
import pygmt
|
||||
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
|
||||
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.data import ATTData
|
||||
import numpy as np
|
||||
|
||||
# %%
|
||||
# plot the traveltime field and adjoint field of the source at the XX iteration
|
||||
# 1. set "output_source_field" to be "True" in the input_params.yaml file
|
||||
|
||||
# Because source parallelizaion is used, the source field is only stored in one out_data_sim_group_XX.h5 file.
|
||||
# For example, if we use 8 processors for source parallelization, we have
|
||||
# src_JC00 is stored in out_data_sim_group_0.h5 file.
|
||||
# src_JC05 is stored in out_data_sim_group_5.h5 file.
|
||||
# src_JC07 is stored in out_data_sim_group_7.h5 file.
|
||||
# src_JC08 is stored in out_data_sim_group_0.h5 file.
|
||||
# src_JC09 is stored in out_data_sim_group_1.h5 file.
|
||||
# src_JC10 is stored in out_data_sim_group_2.h5 file.
|
||||
# ...
|
||||
# src_JC24 is stored in out_data_sim_group_0.h5 file.
|
||||
|
||||
# ---------------- read files ----------------
|
||||
src_name = 'JC05'
|
||||
Nstep = "0007"
|
||||
|
||||
# file names
|
||||
data_file = 'OUTPUT_FILES/out_data_sim_group_5.h5' # data file
|
||||
par_file = 'input_files/input_params.yaml' # parameter file
|
||||
grid_file = 'OUTPUT_FILES/out_data_grid.h5' # grid file
|
||||
group = 'src_%s'%(src_name) # src_${src_name}
|
||||
|
||||
# read traveltime field
|
||||
dataset_time = 'time_field_inv_%s'%(Nstep) # time_field_inv_${Nstep}
|
||||
data = ATTData.read(data_file, par_file, grid_file, group, dataset_time)
|
||||
time_field = data.to_xarray()
|
||||
|
||||
# read adjoint field
|
||||
dataset_adjoint = 'adjoint_field_inv_%s'%(Nstep) # adjoint_field_inv_${Nstep}
|
||||
data = ATTData.read(data_file, par_file, grid_file, group, dataset_adjoint)
|
||||
adjoint_field = data.to_xarray()
|
||||
|
||||
|
||||
# %%
|
||||
import os
|
||||
try:
|
||||
os.mkdir('img')
|
||||
except:
|
||||
pass
|
||||
|
||||
# %%
|
||||
# ---------------- access 3D time field and adjoint field ----------------
|
||||
# we can access 3D dataset:
|
||||
|
||||
dep_1d_array = time_field["dep"]
|
||||
lat_1d_array = time_field["lat"]
|
||||
lon_1d_array = time_field["lon"]
|
||||
|
||||
print("3D array of coordinates. \n dep: ", dep_1d_array.shape, " \n lat: ", lat_1d_array.shape, " \n lon: ", lon_1d_array.shape)
|
||||
|
||||
time_3d_array = time_field[dataset_time]
|
||||
adjoint_3d_array = adjoint_field[dataset_adjoint]
|
||||
|
||||
print("3D array of fields. \n time: ", time_3d_array.shape, " \n adjoint: ", adjoint_3d_array.shape)
|
||||
|
||||
# %%
|
||||
# ---------------- 2D depth profile of time field ----------------
|
||||
|
||||
# interp vel at depth = 20 km
|
||||
depth = 20.0
|
||||
time = time_field.interp_dep(depth, field=dataset_time) # time[i,:] are (lon, lat, vel)
|
||||
|
||||
print("time at depth = ", depth, " km. time:", time.shape, ", (lon, lat, time)")
|
||||
|
||||
# plot
|
||||
fig = pygmt.Figure()
|
||||
fig.basemap(region=[0,2,0,2], frame=["xa1","ya1","+tTraveltime"], projection="M10c") # base map
|
||||
pygmt.makecpt(cmap="jet", series=[0, 30], background=True, reverse=True) # colorbar
|
||||
|
||||
x = time[:,0]; # longitude
|
||||
y = time[:,1]; # latitude
|
||||
value = time[:,2] # traveltime
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=0.04,region=[0,2,0,2])
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
fig.contour(x=x, y=y, z=value, levels=5, pen="1.5p,white") # contour
|
||||
fig.text(text="%d km"%(depth), x = 0.2 , y = 0.1, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a20","y+lTraveltime (s)"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.savefig("img/2_dep_time.png")
|
||||
|
||||
# %%
|
||||
# ---------------- 2D depth profile of adjoint field ----------------
|
||||
|
||||
# interp vel at depth = 20 km
|
||||
depth = 20.0
|
||||
adjoint = adjoint_field.interp_dep(depth, field=dataset_adjoint)
|
||||
|
||||
print("time at depth = ", depth, " km. time:", time.shape, ", (lon, lat, time)")
|
||||
|
||||
# plot
|
||||
fig = pygmt.Figure()
|
||||
fig.basemap(region=[0,2,0,2], frame=["xa1","ya1","+tAdjoint field"], projection="M10c") # base map
|
||||
pygmt.makecpt(cmap="jet", series=[-0.5, 0.5], background=True, reverse=False) # colorbar
|
||||
|
||||
x = time[:,0]; # longitude
|
||||
y = time[:,1]; # latitude
|
||||
value = adjoint[:,2] # traveltime
|
||||
value = value/np.nanmax(np.abs(value))
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=0.04,region=[0,2,0,2])
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
fig.contour(x=x, y=y, z=time[:,2], levels=5, pen="1.5p,white") # contour
|
||||
fig.text(text="%d km"%(depth), x = 0.2 , y = 0.1, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a0.5","y+lAdjoint field"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.savefig("img/2_dep_adjoint.png")
|
||||
|
||||
# %%
|
||||
# ---------------- 2D vertical profile of traveltime field ----------------
|
||||
|
||||
# interp from [0,0.6] in lon-lat to [2,0.6] in lon-lat, gap = 1 km
|
||||
start = [0,0.6]; end = [2,0.6]; gap = 1
|
||||
time_sec = time_field.interp_sec(start, end, field=dataset_time, val = gap) # time_sec[i,:] are (lon, lat, dis, dep, time)
|
||||
|
||||
print("time_sec:", time_sec.shape, ", (lon, lat, distance, depth, time)")
|
||||
|
||||
# plot
|
||||
fig = pygmt.Figure()
|
||||
fig.basemap(region=[0,2,0,40], frame=["xa1+lLongitude","ya20+lDepth (km)","+tTraveltime"], projection="X10c/-2c") # base map
|
||||
pygmt.makecpt(cmap="jet", series=[0, 30], background=True, reverse=True) # colorbar
|
||||
|
||||
x = time_sec[:,0]; # longitude
|
||||
y = time_sec[:,3]; # depth
|
||||
value = time_sec[:,4] # traveltime
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="0.04/1",region=[0,2,0,40])
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
fig.contour(x=x, y=y, z=value, levels=5, pen="1.5p,white") # contour
|
||||
fig.text(text="A", x = 0.1 , y = 5, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
fig.text(text="A@+'@+", x = 1.9 , y = 5, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-2)
|
||||
fig.colorbar(frame = ["a20","y+lTraveltime (s)"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.savefig("img/2_sec_time.png")
|
||||
|
||||
# %%
|
||||
# ---------------- 2D vertical profile of adjoint field ----------------
|
||||
|
||||
# interp from [0,0.6] in lon-lat to [2,0.6] in lon-lat, gap = 1 km
|
||||
start = [0,0.6]; end = [2,0.6]; gap = 1
|
||||
adjoint_sec = adjoint_field.interp_sec(start, end, field=dataset_adjoint, val = gap)
|
||||
|
||||
print("adjoint_sec:", time_sec.shape, ", (lon, lat, distance, depth, adjoint)")
|
||||
|
||||
# plot
|
||||
fig = pygmt.Figure()
|
||||
fig.basemap(region=[0,2,0,40], frame=["xa1+lLongitude","ya20+lDepth (km)","+tAdjoint field"], projection="X10c/-2c") # base map
|
||||
pygmt.makecpt(cmap="jet", series=[-0.5, 0.5], background=True, reverse=False) # colorbar
|
||||
|
||||
x = adjoint_sec[:,0]; # longitude
|
||||
y = adjoint_sec[:,3]; # depth
|
||||
value = adjoint_sec[:,4] # traveltime
|
||||
value = value/np.nanmax(np.abs(value))
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="0.04/1",region=[0,2,0,40])
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
fig.contour(x=x, y=y, z=time_sec[:,4], levels=5, pen="1.5p,white") # contour
|
||||
fig.text(text="A", x = 0.1 , y = 5, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
fig.text(text="A@+'@+", x = 1.9 , y = 5, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-2)
|
||||
fig.colorbar(frame = ["a0.5","y+lAdjoint"], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.savefig("img/2_sec_adjoint.png")
|
||||
|
||||
|
||||
189
examples/scripts_of_plotting/3_plot_kernel.py
Normal file
189
examples/scripts_of_plotting/3_plot_kernel.py
Normal file
@@ -0,0 +1,189 @@
|
||||
# %%
|
||||
import pygmt
|
||||
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
|
||||
|
||||
from pytomoatt.model import ATTModel
|
||||
from pytomoatt.data import ATTData
|
||||
import numpy as np
|
||||
|
||||
# %%
|
||||
# plot sensitivity kernel at the XX iteration
|
||||
# 1. set "output_kernel" to be "True" in the input_params.yaml file
|
||||
|
||||
# ---------------- read files ----------------
|
||||
Nstep = "0007"
|
||||
kernel_list = {} # dictionary to store all the kernels
|
||||
|
||||
# file names
|
||||
data_file = 'OUTPUT_FILES/out_data_sim_group_0.h5' # data file
|
||||
par_file = 'input_files/input_params.yaml' # parameter file
|
||||
grid_file = 'OUTPUT_FILES/out_data_grid.h5' # grid file
|
||||
group = 'model'
|
||||
|
||||
# (Option 1) read original sensitivity kernel
|
||||
# Ks: kernel w.r.t. slowness at the 7-th iteration
|
||||
dataset = 'Ks_inv_%s'%(Nstep)
|
||||
data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# Kxi: kernel w.r.t. xi (anisotropic parameter) at the 7-th iteration
|
||||
dataset = 'Kxi_inv_%s'%(Nstep)
|
||||
data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# Keta: kernel w.r.t. eta (anisotropic parameter) at the 7-th iteration
|
||||
dataset = 'Keta_inv_%s'%(Nstep)
|
||||
data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# %%
|
||||
# (Option 2) read kernel_density
|
||||
# Ks_den: kernel density w.r.t. slowness at the 7-th iteration
|
||||
dataset = 'Ks_density_inv_%s'%(Nstep)
|
||||
data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# Kxi_den: kernel density w.r.t. xi (anisotropic parameter) at the 7-th iteration
|
||||
dataset = 'Kxi_density_inv_%s'%(Nstep)
|
||||
data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# Keta_den: kernel density w.r.t. eta (anisotropic parameter) at the 7-th iteration
|
||||
dataset = 'Keta_density_inv_%s'%(Nstep)
|
||||
data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# %%
|
||||
# kernel density normalization is performed after smoothing. So tag 'Ks_over_Kden_inv_%s'%(Nstep) is not available for version > 1.0.3
|
||||
# # (Option 3) read normalized kernel, K/(k_den)^\zeta
|
||||
# dataset = 'Ks_over_Kden_inv_%s'%(Nstep)
|
||||
# data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
# kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# # Kxi_norm: normalized kernel w.r.t. xi (anisotropic parameter) at the 7-th iteration
|
||||
# dataset = 'Kxi_over_Kden_inv_%s'%(Nstep)
|
||||
# data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
# kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# # Keta_norm: normalized kernel w.r.t. eta (anisotropic parameter) at the 7-th iteration
|
||||
# dataset = 'Keta_over_Kden_inv_%s'%(Nstep)
|
||||
# data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
# kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# %%
|
||||
# this part works for version > 1.0.3
|
||||
# # (Option 3) read kernel density smoothed by multigrid parameterization,
|
||||
# dataset = 'Ks_density_update_inv_%s'%(Nstep)
|
||||
# data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
# kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# # Kxi_norm: normalized kernel w.r.t. xi (anisotropic parameter) at the 7-th iteration
|
||||
# dataset = 'Kxi_density_update_inv_%s'%(Nstep)
|
||||
# data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
# kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# # Keta_norm: normalized kernel w.r.t. eta (anisotropic parameter) at the 7-th iteration
|
||||
# dataset = 'Keta_density_update_inv_%s'%(Nstep)
|
||||
# data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
# kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# %%
|
||||
# (Option 4) read normalized kernel smoothed by multigrid parameterization
|
||||
# Ks_update: smoothed normalized kernel w.r.t. slowness at the 7-th iteration
|
||||
dataset = 'Ks_update_inv_%s'%(Nstep)
|
||||
data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# Kxi_update: smoothed normalized kernel w.r.t. xi (anisotropic parameter) at the 7-th iteration
|
||||
dataset = 'Kxi_update_inv_%s'%(Nstep)
|
||||
data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# Keta_update: smoothed normalized kernel w.r.t. eta (anisotropic parameter) at the 7-th iteration
|
||||
dataset = 'Keta_update_inv_%s'%(Nstep)
|
||||
data = ATTData.read(data_file, par_file, grid_file, group, dataset)
|
||||
kernel_list[dataset] = data.to_xarray()
|
||||
|
||||
# %%
|
||||
import os
|
||||
try:
|
||||
os.mkdir('img')
|
||||
except:
|
||||
pass
|
||||
|
||||
# %%
|
||||
# ---------------- access 3D array ----------------
|
||||
# we can access 3D dataset:
|
||||
|
||||
dep_1d_array = kernel_list['Ks_inv_0007']["dep"]
|
||||
lat_1d_array = kernel_list['Ks_inv_0007']["lat"]
|
||||
lon_1d_array = kernel_list['Ks_inv_0007']["lon"]
|
||||
|
||||
print("3D array of coordinates. \n dep: ", dep_1d_array.shape, " \n lat: ", lat_1d_array.shape, " \n lon: ", lon_1d_array.shape)
|
||||
|
||||
array = kernel_list['Ks_inv_0007']["Ks_inv_0007"]
|
||||
|
||||
print("3D array of kernel. \n Ks: ", array.shape)
|
||||
|
||||
# %%
|
||||
# ---------------- 2D depth profile of kernels ----------------
|
||||
|
||||
for dataset in kernel_list:
|
||||
|
||||
# interp vel at depth = 20 km
|
||||
depth = 20.0
|
||||
kernel = kernel_list[dataset].interp_dep(depth, field=dataset) # kernel[i,:] are (lon, lat, kernel)
|
||||
|
||||
print("kernel at depth = ", depth, " km. kernel:", kernel.shape, ", (lon, lat, kernel)")
|
||||
|
||||
# plot
|
||||
fig = pygmt.Figure()
|
||||
fig.basemap(region=[0,2,0,2], frame=["xa1","ya1","+t%s"%(dataset)], projection="M10c") # base map
|
||||
pygmt.makecpt(cmap="jet", series=[-0.5, 0.5], background=True, reverse=True) # colorbar
|
||||
|
||||
x = kernel[:,0]; # longitude
|
||||
y = kernel[:,1]; # latitude
|
||||
value = kernel[:,2]/np.nanmax(np.abs(kernel[:,2])) # traveltime
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing=0.04,region=[0,2,0,2])
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
fig.text(text="%d km"%(depth), x = 0.2 , y = 0.1, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a0.5","y+l%s"%(dataset)], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.savefig("img/3_dep_%s.png"%(dataset))
|
||||
|
||||
# %%
|
||||
# ---------------- 2D vertical profile of kernels ----------------
|
||||
|
||||
for dataset in kernel_list:
|
||||
|
||||
# interp from [0,0.6] in lon-lat to [2,0.6] in lon-lat, gap = 1 km
|
||||
start = [0,0.6]; end = [2,0.6]; gap = 1
|
||||
kernel_sec = kernel_list[dataset].interp_sec(start, end, field=dataset, val = gap) # kernel_sec[i,:] are (lon, lat, dis, dep, kernel)
|
||||
|
||||
print("kernel_sec:", kernel_sec.shape, ", (lon, lat, distance, depth, kernel)")
|
||||
|
||||
# plot
|
||||
fig = pygmt.Figure()
|
||||
fig.basemap(region=[0,2,0,40], frame=["xa1+lLongitude","ya20+lDepth (km)","+t%s"%(dataset)], projection="X10c/-2c") # base map
|
||||
pygmt.makecpt(cmap="jet", series=[-0.5, 0.5], background=True, reverse=True) # colorbar
|
||||
|
||||
x = kernel_sec[:,0]; # longitude
|
||||
y = kernel_sec[:,3]; # depth
|
||||
value = kernel_sec[:,4]/np.nanmax(np.abs(kernel_sec[:,4])) # traveltime
|
||||
grid = pygmt.surface(x=x, y=y, z=value, spacing="0.04/1",region=[0,2,0,40])
|
||||
|
||||
fig.grdimage(grid = grid) # plot figure
|
||||
fig.text(text="A", x = 0.1 , y = 5, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
fig.text(text="A@+'@+", x = 1.9 , y = 5, font = "14p,Helvetica-Bold,black", fill = "white")
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-2)
|
||||
fig.colorbar(frame = ["a0.5","y+l%s"%(dataset)], position="+e+w4c/0.3c+h")
|
||||
|
||||
fig.savefig("img/3_sec_%s.png"%(dataset))
|
||||
|
||||
|
||||
54
examples/scripts_of_plotting/4_plot_earthquake_station.py
Normal file
54
examples/scripts_of_plotting/4_plot_earthquake_station.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# %%
|
||||
import pygmt
|
||||
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
|
||||
|
||||
|
||||
# %%
|
||||
from pytomoatt.src_rec import SrcRec
|
||||
|
||||
# read src_rec_file
|
||||
sr = SrcRec.read("input_files/src_rec_file.dat")
|
||||
|
||||
# get the coordinates of the stations and earthquakes
|
||||
stations = sr.receivers[['stlo','stla','stel']].values.T
|
||||
earthquakes = sr.sources[['evlo','evla','evdp']].values.T
|
||||
|
||||
print(stations.shape)
|
||||
print(earthquakes.shape)
|
||||
|
||||
# %%
|
||||
# plot earthquakes and locations
|
||||
|
||||
fig = pygmt.Figure()
|
||||
|
||||
pygmt.makecpt(cmap="jet", series=[0, 40], background=True, reverse=True) # colorbar
|
||||
|
||||
# -------- horizontal view (x-y) --------
|
||||
fig.basemap(region=[0,2,0,2], frame=["xa1","ya1","NsWe"], projection="M10c") # base map
|
||||
# earthquakes
|
||||
fig.plot(x = earthquakes[0,:], y = earthquakes[1,:], cmap = True, style = "c0.1c", fill = earthquakes[2,:])
|
||||
# stations
|
||||
fig.plot(x = stations[0,:], y = stations[1,:], style = "t0.4c", fill = "blue", pen = "black", label = "Station")
|
||||
|
||||
|
||||
# -------- vertical view (x-z) --------
|
||||
fig.shift_origin(xshift=0, yshift=-3)
|
||||
fig.basemap(region=[0,2,0,40], frame=["xa1","ya20+lDepth (km)","NsWe"], projection="X10c/-2c") # base map
|
||||
# earthquakes
|
||||
fig.plot(x = earthquakes[0,:], y = earthquakes[2,:], cmap = True, style = "c0.1c", fill = earthquakes[2,:])
|
||||
|
||||
|
||||
# -------- vertical view (z-y) --------
|
||||
fig.shift_origin(xshift=11, yshift=3)
|
||||
fig.basemap(region=[0,40,0,2], frame=["xa20+lDepth (km)","ya1","NsWe"], projection="X2c/10c") # base map
|
||||
# earthquakes
|
||||
fig.plot(x = earthquakes[2,:], y = earthquakes[1,:], cmap = True, style = "c0.1c", fill = earthquakes[2,:])
|
||||
|
||||
|
||||
# colorbar
|
||||
fig.shift_origin(xshift=0, yshift=-1.5)
|
||||
fig.colorbar(frame = ["a20","x+lDepth (km)"], position="+e+w2c/0.3c+h")
|
||||
|
||||
fig.savefig("img/4_earthquakes_and_stations.png")
|
||||
|
||||
|
||||
124
examples/scripts_of_plotting/5_plot_objective_function.py
Normal file
124
examples/scripts_of_plotting/5_plot_objective_function.py
Normal file
@@ -0,0 +1,124 @@
|
||||
# %%
|
||||
import sys
|
||||
sys.path.append('../utils')
|
||||
import functions_for_data as ffd
|
||||
|
||||
# %%
|
||||
# read objective function
|
||||
|
||||
path = "OUTPUT_FILES"
|
||||
full_curve, location_curve, model_curve = ffd.read_objective_function_file(path)
|
||||
|
||||
print("full_curve: ", full_curve.shape, ", the total objective function value during the inversion, including relocation and model update")
|
||||
print("location_curve: ", location_curve.shape, ", the objective function value during the relocation step")
|
||||
print("model_curve: ", model_curve.shape, ", the objective function value during the model update step")
|
||||
|
||||
print("The first index is iteraion number, the second index is the objective function value vector")
|
||||
|
||||
|
||||
# %%
|
||||
# (Option 1) objective function value
|
||||
full_obj = full_curve[:,0]
|
||||
location_obj = location_curve[:,0]
|
||||
model_obj = model_curve[:,0]
|
||||
|
||||
# (Option 2) objective function value for only traveltime
|
||||
full_obj_tt = full_curve[:,1]
|
||||
location_obj_tt = location_curve[:,1]
|
||||
model_obj_tt = model_curve[:,1]
|
||||
|
||||
# (Option 3) objective function value for only common source differential arrival time
|
||||
full_obj_cs = full_curve[:,2]
|
||||
location_obj_cs = location_curve[:,2]
|
||||
model_obj_cs = model_curve[:,2]
|
||||
|
||||
# (Option 4) objective function value for only common receiver differential arrival time
|
||||
full_obj_cr = full_curve[:,3]
|
||||
location_obj_cr = location_curve[:,3]
|
||||
model_obj_cr = model_curve[:,3]
|
||||
|
||||
# (Option 5) objective function value for teleseismic differential arrival time
|
||||
full_obj_tele = full_curve[:,4]
|
||||
location_obj_tele = location_curve[:,4]
|
||||
model_obj_tele = model_curve[:,4]
|
||||
|
||||
# (Option 6) mean value of all data residual
|
||||
full_mean = full_curve[:,5]
|
||||
location_mean = location_curve[:,5]
|
||||
model_mean = model_curve[:,5]
|
||||
|
||||
# (Option 7) standard deviation of all data residual
|
||||
full_std = full_curve[:,6]
|
||||
location_std = location_curve[:,6]
|
||||
model_std = model_curve[:,6]
|
||||
|
||||
# (Option 8) mean value of residuals of traveltime
|
||||
full_mean_tt = full_curve[:,7]
|
||||
location_mean_tt = location_curve[:,7]
|
||||
model_mean_tt = model_curve[:,7]
|
||||
|
||||
# (Option 9) standard deviation of residuals of traveltime
|
||||
full_std_tt = full_curve[:,8]
|
||||
location_std_tt = location_curve[:,8]
|
||||
model_std_tt = model_curve[:,8]
|
||||
|
||||
# (Option 10) mean value of residuals of common source differential arrival time
|
||||
full_mean_cs = full_curve[:,9]
|
||||
location_mean_cs = location_curve[:,9]
|
||||
model_mean_cs = model_curve[:,9]
|
||||
|
||||
# (Option 11) standard deviation of residuals of common source differential arrival time
|
||||
full_std_cs = full_curve[:,10]
|
||||
location_std_cs = location_curve[:,10]
|
||||
model_std_cs = model_curve[:,10]
|
||||
|
||||
# (Option 12) mean value of residuals of common receiver differential arrival time
|
||||
full_mean_cr = full_curve[:,11]
|
||||
location_mean_cr = location_curve[:,11]
|
||||
model_mean_cr = model_curve[:,11]
|
||||
|
||||
# (Option 13) standard deviation of residuals of common receiver differential arrival time
|
||||
full_std_cr = full_curve[:,12]
|
||||
location_std_cr = location_curve[:,12]
|
||||
model_std_cr = model_curve[:,12]
|
||||
|
||||
# (Option 14) mean value of residuals of teleseismic differential arrival time
|
||||
full_mean_tele = full_curve[:,13]
|
||||
location_mean_tele = location_curve[:,13]
|
||||
model_mean_tele = model_curve[:,13]
|
||||
|
||||
# (Option 15) standard deviation of residuals of teleseismic differential arrival time
|
||||
full_std_tele = full_curve[:,14]
|
||||
location_std_tele = location_curve[:,14]
|
||||
model_std_tele = model_curve[:,14]
|
||||
|
||||
|
||||
# %%
|
||||
import os
|
||||
try:
|
||||
os.mkdir("img")
|
||||
except:
|
||||
pass
|
||||
|
||||
# %%
|
||||
# plot objective functin reduction
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
|
||||
plt.figure(figsize=(10, 6))
|
||||
ax = plt.subplot(1, 1, 1)
|
||||
|
||||
ax.plot(model_obj/np.max(model_obj), label='objective function', linewidth=2)
|
||||
ax.set_xlim([-0.2, len(model_obj)-0.8])
|
||||
ax.set_ylim([0, 1.1])
|
||||
ax.grid()
|
||||
ax.set_xlabel('Iteration number',fontsize=14)
|
||||
ax.set_ylabel('Normalized value',fontsize=14)
|
||||
ax.tick_params(axis='x', labelsize=14)
|
||||
ax.tick_params(axis='y', labelsize=14)
|
||||
ax.legend(fontsize=14)
|
||||
|
||||
plt.savefig('img/5_objective_function_reduction.png', dpi=300, bbox_inches='tight', edgecolor='w', facecolor='w')
|
||||
|
||||
|
||||
86
examples/scripts_of_plotting/6_plot_data_residual.py
Normal file
86
examples/scripts_of_plotting/6_plot_data_residual.py
Normal file
@@ -0,0 +1,86 @@
|
||||
# %%
|
||||
import sys
|
||||
sys.path.append('../utils')
|
||||
import functions_for_data as ffd
|
||||
|
||||
|
||||
# %%
|
||||
# synthetic and observational traveltime files in the initial and final models
|
||||
|
||||
file_init_syn = "OUTPUT_FILES/src_rec_file_inv_0000_reloc_0000.dat" # synthetic traveltime in the initial model
|
||||
file_init_obs = "input_files/src_rec_file.dat" # observational traveltime in the initial model
|
||||
|
||||
file_final_syn = "OUTPUT_FILES/src_rec_file_inv_0009_reloc_0009.dat" # synthetic traveltime in the final model
|
||||
file_final_obs = "OUTPUT_FILES/src_rec_file_inv_0009_reloc_0009_obs.dat" # observational traveltime in the final model
|
||||
|
||||
|
||||
# %%
|
||||
# from pytomoatt.src_rec import SrcRec
|
||||
# init_syn = SrcRec.read(file_init_syn)
|
||||
# init_obs = SrcRec.read(file_init_obs)
|
||||
|
||||
# final_syn = SrcRec.read(file_final_syn)
|
||||
# final_obs = SrcRec.read(file_final_obs)
|
||||
|
||||
# %%
|
||||
ev, st = ffd.read_src_rec_file(file_init_syn)
|
||||
time_init_syn = ffd.data_dis_time(ev, st)[1] # synthetic traveltime in the initial model
|
||||
|
||||
ev, st = ffd.read_src_rec_file(file_init_obs)
|
||||
time_init_obs = ffd.data_dis_time(ev, st)[1] # observational traveltime in the initial model
|
||||
|
||||
ev, st = ffd.read_src_rec_file(file_final_syn)
|
||||
time_final_syn = ffd.data_dis_time(ev, st)[1] # synthetic traveltime in the final model
|
||||
|
||||
ev, st = ffd.read_src_rec_file(file_final_obs)
|
||||
time_final_obs = ffd.data_dis_time(ev, st)[1] # observational traveltime in the final model
|
||||
|
||||
# %%
|
||||
import os
|
||||
try:
|
||||
os.mkdir("img")
|
||||
except:
|
||||
pass
|
||||
|
||||
# %%
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
fig = plt.figure(figsize=(8,8))
|
||||
ax = fig.add_subplot(111)
|
||||
|
||||
range_l = -1.5
|
||||
range_r = 1.5
|
||||
Nbar = 20
|
||||
|
||||
bins=np.linspace(range_l,range_r,Nbar)
|
||||
error_init = time_init_syn - time_init_obs
|
||||
error_final = time_final_syn - time_final_obs
|
||||
|
||||
tag1 = "initial mode"
|
||||
tag2 = "final mode"
|
||||
|
||||
hist_init, _, _ = ax.hist(error_init,bins=bins,histtype='step', edgecolor = "red", linewidth = 2,
|
||||
label = "%s: std = %5.3f s, mean = %5.3f s"%(tag1,np.std(error_init),np.mean(error_init)))
|
||||
|
||||
hist_final, _, _ = ax.hist(error_final,bins=bins,alpha = 0.5, color = "blue",
|
||||
label = "%s: std = %5.3f s, mean = %5.3f s"%(tag2,np.std(error_final),np.mean(error_final)))
|
||||
|
||||
print("residual for ",tag1," model is: ","mean: ",np.mean(error_init),"sd: ",np.std(error_init))
|
||||
print("residual for ",tag2," model is: ","mean: ",np.mean(error_final),"sd: ",np.std(error_final))
|
||||
ax.legend(fontsize=14)
|
||||
|
||||
ax.set_xlim(range_l - abs(range_l)*0.1,range_r + abs(range_r)*0.1)
|
||||
ax.set_ylim(0,1.3*max(max(hist_init),max(hist_final)))
|
||||
|
||||
ax.tick_params(axis='x',labelsize=18)
|
||||
ax.tick_params(axis='y',labelsize=18)
|
||||
ax.set_ylabel('Count of data',fontsize=18)
|
||||
ax.set_xlabel('Traveltime residuals (s)',fontsize=18)
|
||||
ax.set_title("$t_{syn} - t_{obs}$",fontsize=18)
|
||||
ax.grid()
|
||||
|
||||
plt.savefig("img/6_data_residual.png",dpi=300, bbox_inches='tight', edgecolor='w', facecolor='w' )
|
||||
plt.show()
|
||||
|
||||
|
||||
61
examples/scripts_of_plotting/7_plot_inversion_grid.py
Normal file
61
examples/scripts_of_plotting/7_plot_inversion_grid.py
Normal file
@@ -0,0 +1,61 @@
|
||||
# %%
|
||||
import pygmt
|
||||
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
|
||||
|
||||
|
||||
# %%
|
||||
import sys
|
||||
sys.path.append('../utils')
|
||||
import functions_for_data as ffd
|
||||
|
||||
# %%
|
||||
# read inversion grid file
|
||||
|
||||
inv_grid_vel, inv_grid_ani = ffd.read_inversion_grid_file("OUTPUT_FILES")
|
||||
|
||||
print("inversion grid for velocity: ", inv_grid_vel.shape)
|
||||
print("inversion grid for anisotropy: ", inv_grid_vel.shape)
|
||||
|
||||
Nset = inv_grid_vel.shape[0]
|
||||
Ngrid = inv_grid_vel.shape[1]
|
||||
|
||||
colorlist = ["green","blue","red","purple","orange","yellow","black","gray","pink","cyan"]
|
||||
|
||||
# %%
|
||||
# plot earthquakes and locations
|
||||
|
||||
fig = pygmt.Figure()
|
||||
|
||||
pygmt.makecpt(cmap="jet", series=[0, 40], background=True, reverse=True) # colorbar
|
||||
|
||||
# -------- horizontal view (x-y) --------
|
||||
fig.basemap(region=[0,2,0,2], frame=["xa1","ya1","NsWe"], projection="M10c") # base map
|
||||
# plot inversion grid
|
||||
for igrid in range(Nset):
|
||||
x = inv_grid_vel[igrid,:,0]
|
||||
y = inv_grid_vel[igrid,:,1]
|
||||
fig.plot(x=x, y=y, style="c0.1c", fill=colorlist[igrid])
|
||||
|
||||
# -------- vertical view (x-z) --------
|
||||
fig.shift_origin(xshift=0, yshift=-3)
|
||||
fig.basemap(region=[0,2,0,40], frame=["xa1","ya20+lDepth (km)","NsWe"], projection="X10c/-2c") # base map
|
||||
# plot inversion grid
|
||||
for igrid in range(Nset):
|
||||
x = inv_grid_vel[igrid,:,0]
|
||||
y = inv_grid_vel[igrid,:,2]
|
||||
fig.plot(x=x, y=y, style="c0.1c", fill=colorlist[igrid])
|
||||
|
||||
|
||||
# -------- vertical view (z-y) --------
|
||||
fig.shift_origin(xshift=11, yshift=3)
|
||||
fig.basemap(region=[0,40,0,2], frame=["xa20+lDepth (km)","ya1","NsWe"], projection="X2c/10c") # base map
|
||||
# plot inversion grid
|
||||
for igrid in range(Nset):
|
||||
x = inv_grid_vel[igrid,:,2]
|
||||
y = inv_grid_vel[igrid,:,1]
|
||||
fig.plot(x=x, y=y, style="c0.1c", fill=colorlist[igrid])
|
||||
|
||||
|
||||
fig.savefig("img/7_inversion_grid.png")
|
||||
|
||||
|
||||
16
examples/scripts_of_plotting/README.md
Normal file
16
examples/scripts_of_plotting/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Scripts of plotting
|
||||
|
||||
It includes examples to illustrate the output file of TomoATT
|
||||
|
||||
|
||||
Python modules are required to initiate the inversion and to plot final results:
|
||||
- h5py
|
||||
- PyTomoAT
|
||||
- Pygmt
|
||||
- gmt
|
||||
|
||||
Run this example:
|
||||
|
||||
1. Run bash script `bash run_this_example.sh` to execute the test.
|
||||
|
||||
|
||||
21
examples/scripts_of_plotting/prepare_files.py
Normal file
21
examples/scripts_of_plotting/prepare_files.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# %%
|
||||
# download model file from Zenodo
|
||||
import os
|
||||
import requests
|
||||
|
||||
url = 'https://zenodo.org/records/14160818/files/files_for_plotting.tar.gz?download=1'
|
||||
|
||||
path = "files_for_plotting.tar.gz"
|
||||
|
||||
# check file existence
|
||||
if not os.path.exists(path):
|
||||
print("Downloading src_rec_file.dat from Zenodo...")
|
||||
print("The file is about 400 MB, so it may take a while.")
|
||||
response = requests.get(url, stream=True)
|
||||
with open(path, 'wb') as out_file:
|
||||
out_file.write(response.content)
|
||||
print("Download complete.")
|
||||
else:
|
||||
print("files_for_plotting.tar.gz already exists.")
|
||||
|
||||
|
||||
50
examples/scripts_of_plotting/run_this_example.sh
Normal file
50
examples/scripts_of_plotting/run_this_example.sh
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Some script to plot figures for the output file of TomoATT
|
||||
|
||||
python prepare_files.py # download the files for plotting
|
||||
tar -xf files_for_plotting.tar.gz # extract the files
|
||||
|
||||
|
||||
# Test 1: plot velocity perturbation and azimuthal anisotropy fields to generate
|
||||
# img/1_dep_vel.png 2D velocity perturbation at 20 km depth
|
||||
# img/1_dep_ani.png 2D azimuthal anisotropy at 20 km depth
|
||||
# img/1_sec_vel.png 2D velocity perturbation along vertical section
|
||||
python 1_plot_model.py
|
||||
|
||||
# Test 2: plot traveltime and adjoint fields to generate
|
||||
# img/2_dep_time.png 2D traveltime field at 20 km depth
|
||||
# img/2_sec_time.png 2D traveltime field along vertical section
|
||||
# img/2_dep_adjoint.png 2D adjoint field at XX depth
|
||||
# img/2_sec_adjoint.png 2D adjoint field along vertical section
|
||||
python 2_plot_time_field.py
|
||||
|
||||
# Test 3: plot kernels to generate
|
||||
# img/3_dep_Ks_inv_0007.png Ks: original kernel w.r.t slowness at 20 km depth
|
||||
# img/3_dep_Ks_density_inv_0007.png Kden: kernel density w.r.t slowness at 20 km depth
|
||||
# img/3_dep_Ks_over_Kden_inv_0007.png Ks/Kden^{\zeta}: normalized kernel w.r.t slowness at 20 km depth
|
||||
# img/3_dep_Ks_update_inv_0007.png smoothed normalized kernel w.r.t slowness at 20 km depth
|
||||
# img/3_sec_Ks_inv_0007.png Ks: original kernel w.r.t slowness along vertical section
|
||||
# img/3_sec_Ks_density_inv_0007.png Kden: kernel density w.r.t slowness along vertical section
|
||||
# img/3_sec_Ks_over_Kden_inv_0007.png Ks/Kden^{\zeta}: normalized kernel w.r.t slowness along vertical section
|
||||
# img/3_sec_Ks_update_inv_0007.png smoothed normalized kernel w.r.t slowness along vertical section
|
||||
# and the same for kernels w.r.t xi and eta (azimuthal anisotropy)
|
||||
python 3_plot_kernel.py
|
||||
|
||||
# Test 4: plot earthquakes and stations to generate
|
||||
# img/4_earthquakes_and_stations.png the location of earthquakes and stations
|
||||
python 4_plot_earthquake_station.py
|
||||
|
||||
# Test 5: plot objective function reduction to generate
|
||||
# img/5_objective_function_reduction.png the reduction of objective function value
|
||||
python 5_plot_objective_function.py
|
||||
|
||||
# Test 6: plot traveltime residuals to generate
|
||||
# img/6_data_residual.png the traveltime residuals
|
||||
python 6_plot_data_residual.py
|
||||
|
||||
# Test 7: plot inversion grid to generate
|
||||
# img/7_inversion_grid.png the inversion grid
|
||||
python 7_plot_inversion_grid.py
|
||||
|
||||
|
||||
BIN
examples/src_rec_file_instruction.jpg
Normal file
BIN
examples/src_rec_file_instruction.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.9 MiB |
2719
examples/utils/functions_for_data.ipynb
Normal file
2719
examples/utils/functions_for_data.ipynb
Normal file
File diff suppressed because it is too large
Load Diff
2414
examples/utils/functions_for_data.py
Normal file
2414
examples/utils/functions_for_data.py
Normal file
File diff suppressed because it is too large
Load Diff
15
examples/utils/svel13_chen.cpt
Normal file
15
examples/utils/svel13_chen.cpt
Normal file
@@ -0,0 +1,15 @@
|
||||
-0.7000E+01 166 0 0 -0.6000E+01 225 0 0
|
||||
-0.6000E+01 225 0 0 -0.5000E+01 255 75 0
|
||||
-0.5000E+01 255 75 0 -0.4000E+01 255 132 0
|
||||
-0.4000E+01 255 132 0 -0.3000E+01 255 198 0
|
||||
-0.3000E+01 255 198 0 -0.2000E+01 255 255 0
|
||||
-0.2000E+01 255 255 0 -0.1000E+00 255 255 255
|
||||
-0.1000E+00 255 255 255 0.1000E+00 255 255 255
|
||||
0.1000E+00 255 255 255 0.2000E+01 0 255 255
|
||||
0.2000E+01 0 255 255 0.3000E+01 90 205 255
|
||||
0.3000E+01 90 205 255 0.4000E+01 26 160 255
|
||||
0.4000E+01 26 160 255 0.5000E+01 0 100 255
|
||||
0.5000E+01 0 100 255 0.6000E+01 0 50 200
|
||||
0.6000E+01 0 50 200 0.7000E+01 0 10 160
|
||||
B 166 0 0
|
||||
F 0 10 160
|
||||
Reference in New Issue
Block a user