(15) Animating 2-D coupled gridding via SVD

Gridding via elastically coupled Green’s splines via gpsgridder is similar to greenspline gridding in that a SVD-based solution allows for the use of a subset of the eigenvalues. While a good first step is to use 25% of them, this animation shows the solutions for all choices of eigenvalues and tracks the reduction of misfit (both total and separately for the east and north components.) The movie shares the same data and setup as one of our test scripts (gpsgridder1.sh) but has been “weaponized” to do it via animation. Note as we include the contributions from the tiniest eigenvalues we rapidly “improve” the misfit while adding spurious variations to the solution. The moral is to not try to fit the data exactly.

#!/usr/bin/env bash
#
# Gridding via elastically coupled Green's splines is similar to greenspline gridding
# in that a SVD-based solution allows for the use of a subset of the eigenvalues.
# While a good first step is to use 25% of them, this animation shows the solutions
# for all choices of eigenvalues and tracks the reduction of misfit (both total and
# separately for the east and north components.)  The movie shares the same data and
# setup as one of our test scripts (gpsgridder1.sh) but has been weaponized to do it
# via animation.  Note as we include the contributions from the tiniest eigenvalues
# we rapidly "improve" the misfit while adding spurious variations to the solution.
# The moral is to not try to fit the data exactly.
#
# The finished movie is available in our YouTube channel as well:
# https://youtu.be/Pvvc4vb8G4Y
#
# The script took ~20 minutes to render on a 24-core MacPro 2013, with most of the
# time being used to solve for the cumulative and incremental grid components.

# 0. A few common variables to include
cat << 'EOF' > inc.sh
INC=5m	# Desired grid spacing
DEC=2	# Let grdvector only plot every other node
R=-R122.5W/115W/32.5N/38N	# Area of interest
RATE_CUM=50 # This is in mm/yr or km/Myr - change to use another scalebar
RATE_INC=5 # This is in mm/yr or km/Myr - change to use another scalebar
EOF
# 1. Background script doing the hard work plus making background map
cat << 'EOF' > pre.sh
gmt begin
	# Prepare the GPS data set for use with a 1x1 arc minute grid
	gmt set MAP_VECTOR_SHAPE 0.5
	gmt select @wus_gps_final.txt -R122.5W/115W/32.5N/40N -fg -o0:5 > data.lluv
#	Use blockmean to avoid aliasing
	gmt blockmean $R -I${INC} data.lluv -fg -i0:2,4 -W > blk.llu
	gmt blockmean data.lluv -fg -i0,1,3,5 -W > blk.llv
	gmt convert -A blk.llu blk.llv -o0:2,6,3,7 > blk.lluv
	gmt select blk.lluv $R -fg | awk '{ print($0," 0 ") }' > data.lluvenct
#
#	Do the gridding. There are 2682 data and here we evaluate all possible solutions
	gmt gpsgridder $R -I${INC} -Gtmp.grd blk.lluv -fg -Emisfit.txt -Fd8 -C+c+i -S0.5 -V
#
#	Mask the grids
	cat <<- END > corner.ll
	-114.9 37.
	-114.9 40.1
	-118 40.1
	-115.50 37
	-115.25 32.5
	-114.9 32.5
	-114.9 37
	END
	gmt grdlandmask -Gtmp_mask1.grd -Df
	gmt grdmask -Rtmp_mask1.grd corner.ll -Gtmp_mask2.grd -N1/0/0
	gmt grdmath tmp_mask1.grd tmp_mask2.grd MUL 0 NAN = mask.grd

#	Make a plot of GPS velocity vectors
	gmt coast -Rmask.grd -JM4.2i -Glightgray -Ba1f30m -BWSne -Df -X0.4i -Y0.25i -Wfaint
	gmt plot @CA_fault_data.txt -W0.5p
	gmt velo data.lluvenct -Se.008i/0.95+f8p -A9p -W0.2p,red

#	Place the scale using a geovector of length RATE_CUM
	echo 121.5W 33N 90 ${RATE_CUM}k   | gmt plot -S=0.06i+e+jc -Gblue -W1p,blue
	echo 121.5W 33N ${RATE_CUM} mm/yr | gmt text -F+f8p+jCB -D0/0.07i
#	Map for incremental vectors
	gmt coast -Glightgray -Ba1f30m -BESnw -Df -X4.4i -Wfaint
	gmt plot @CA_fault_data.txt -W0.5p
#	Place the scale using a geovector of length RATE_INC (10x scaling)
	echo 121.5W 33N 90 ${RATE_CUM}k   | gmt plot -S=0.06i+e+jc -Gblue -W1p,blue
	echo 121.5W 33N ${RATE_INC} mm/yr | gmt text -F+f8p+jCB -D0/0.07i
gmt end
EOF
# 2. Main script for the frames
cat << 'EOF' > main.sh
gmt begin
	# Prepare the masked cumulative u,v grids
	gmt grdmath tmp_u_cum_${MOVIE_ITEM}.grd mask.grd MUL = GPS_u.grd
	gmt grdmath tmp_v_cum_${MOVIE_ITEM}.grd mask.grd MUL = GPS_v.grd
	# Plot models
	# Shrink down heads of vectors shorter than 10 km
	gmt grdvector GPS_u.grd GPS_v.grd -Ix${DEC}/${DEC} -JM4.2i -Q0.06i+e+n10 -Gblue -W0.2p,blue -S100i -X0.4i -Y0.25i
	# Prepare the masked incremental grids scaled by 10
	gmt grdmath tmp_u_inc_${MOVIE_ITEM}.grd mask.grd MUL 10 MUL = GPS_du.grd
	gmt grdmath tmp_v_inc_${MOVIE_ITEM}.grd mask.grd MUL 10 MUL = GPS_dv.grd
	gmt grdvector GPS_du.grd GPS_dv.grd -Ix${DEC}/${DEC} -Q0.06i+e+n10 -Gblue -W0.2p,blue -S100i -X4.45i
	gmt plot misfit.txt -i0,4 -qi0:${MOVIE_FRAME} -R0/${MOVIE_NFRAMES}/0/7 -JX8.6i/0.7i -X-4.45i -Y4.0i -B -BWSrt -W0.25p,green
	# Show decrease in rms misfits
	gmt plot misfit.txt -i0,5 -qi0:${MOVIE_FRAME} -W0.25p,blue
	gmt plot misfit.txt -i0,3 -qi0:${MOVIE_FRAME} -W1p,red
gmt end
EOF
# 3. Run the movie
gmt movie main.sh -Iinc.sh -Sbpre.sh -CHD -Nanim15 -H8 -M210,png -Tmisfit.txt -Lf+jTC+t"Cumulative and Incremental Vector Contributions for Eigenvalue %4.4d" \
	-Ls"rms@-u@-"+f12p,Helvetica,green+jTR+o0.5i/0.4i -Ls"rms@-v@-"+f12p,Helvetica,blue+jTR+o0.5i/0.55i -Ls"rms@-c@-"+f12p,Helvetica,red+jTR+o0.5i/0.7i -Fmp4 -V -Zs