Skip to Content

Plot models

Here, we demonstrate how to visualize the traveltime field and adjoint field. First, we load necessary Python modules

import pygmt pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<") from pytomoatt.data import ATTData import numpy as np import os try: os.mkdir('img') except: pass

1. Read model files

Using the PyTomoATT module, we read the time field and adjoint_field of the source JC05 at the 7-th iteration as time_field and adjoint_field, repsectively.

/src_${src_name}/time_field_inv_${Nstep} and /src_${src_name}/adjoint_field_inv_${Nstep} are the paths of traveltime and adjoint fields in the output HDF5 file out_data_sim_group_XX.h5.

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

Since source parallelization is applied, fileds of each source is store in a specific file, named as out_data_sim_group_XX.h5. Users can check which sources are contained in the specific out_data_sim_group_XX.h5 file, e.g.,

h5ls OUTPUT_FILES/out_data_sim_group_5.h5

The output log is

src_JC05 Group src_JC13 Group src_JC21 Group

src_${source_name} means that the source is contained in the file out_data_sim_group_0.h5.

Furthermore, using

h5ls OUTPUT_FILES/out_data_sim_group_5.h5/src_JC05

yields

adjoint_field_inv_0000 Dataset {226981} adjoint_field_inv_0001 Dataset {226981} adjoint_field_inv_0002 Dataset {226981} adjoint_field_inv_0003 Dataset {226981} adjoint_field_inv_0004 Dataset {226981} adjoint_field_inv_0005 Dataset {226981} adjoint_field_inv_0006 Dataset {226981} adjoint_field_inv_0007 Dataset {226981} adjoint_field_inv_0008 Dataset {226981} adjoint_field_inv_0009 Dataset {226981} time_field_inv_0000 Dataset {226981} time_field_inv_0001 Dataset {226981} time_field_inv_0002 Dataset {226981} time_field_inv_0003 Dataset {226981} time_field_inv_0004 Dataset {226981} time_field_inv_0005 Dataset {226981} time_field_inv_0006 Dataset {226981} time_field_inv_0007 Dataset {226981} time_field_inv_0008 Dataset {226981} time_field_inv_0009 Dataset {226981}

It contains traveltime fields and adjoint fields at all iterations.

Users can easily check the 3D numpy arrays of

  • traveltime field time_3d_array;
  • adjoint time field adjoint_3d_array; and 1D numpy arrays of
  • depth coordinates dep_1d_array;
  • latitude cooridinates lat_1d_array;
  • longitude coordinates lon_1d_array.
# ---------------- 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)

2. Plot horizontal profile of the traveltime field

Here, we plot the horizontal profile of traveltime field at 20 km depth.

First, we extract the 2D profiles of the traveltime field at 20 km depth as time.

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

Second, we generate the grid object for PyGMT plotting

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

Finally, we plot the horizontal profile, and output the figure as img/2_dep_time.png.

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

The figure is shown as below. The time contour is not a perfect circle due to velocity perturbation and azimuthal anisotrop (see models). img

2. Plot vertical profile of the traveltime field

Here, we plot the vertical profile of traveltime field

First, we extract the 2D profiles of the traveltime field from (0,0.6) to (2,0.6). as time_sec.

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

Second, we generate the grid object for PyGMT plotting

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

Finally, we plot the horizontal profile, and output the figure as img/2_sec_time.png.

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

The figure is shown as below. img

3. Plot horizontal profile of the adjoint field

Here, we plot the horizontal profile of adjoint field at 20 km depth.

First, we extract the 2D profiles of the adjoint field at 20 km depth as adjoint.

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

Second, we generate the grid object for PyGMT plotting

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

Finally, we plot the horizontal profile, and output the figure as img/2_dep_adjoint.png.

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

The figure is shown as below. The kernel looks a little bit thick due to the smoothing of coarse discretized mesh grid. img

4. Plot vertical profile of the adjoint field

Here, we plot the vertical profile of adjoint field.

First, we extract the 2D profiles of the adjoint field from (0,0.6) to (2,0.6). as adjoint_sec.

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

Second, we generate the grid object for PyGMT plotting

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

Finally, we plot the vertical profile, and output the figure as img/2_sec_adjoint.png.

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

The figure is shown as below. img

Last updated on