initial upload

This commit is contained in:
2025-12-17 10:53:43 +08:00
commit f3f1778f77
308 changed files with 129940 additions and 0 deletions

View 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")

View 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")

View 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))

View 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")

View 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')

View 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()

View 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")

View 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.

View 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.")

View 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