(8) | ||
(9) |
A seismic trace is a signal d(t) recorded at some constant x. We can convert the trace to a ``vertical propagation'' signal by stretching t to .This process is called ``normal moveout correction'' (NMO). Typically we have many traces at different x distances each of which theoretically produces the same hypothetical zero-offset trace. Figure 1 shows a marine shot profile before and after NMO correction at the water velocity. You can notice that the wave packet reflected from the ocean bottom is approximately a constant width on the raw data. After NMO, however, this waveform broadens considerably--a phenomenon known as ``NMO stretch."
stretch
Figure 1 Marine data moved out with water velocity. Input on the left, output on the right. Press button for movie sweeping through velocity (actually through slowness squared). |
The NMO transformation is representable as a square matrix. The matrix is a -plane containing all zeros except an interpolation operator centered along the hyperbola. The dots in the matrix below are zeros. The input signal dt is put into the vector .The output vector --i.e., the NMO'ed signal--is simply (d6,d6,d6, d7,d7, d8,d8, d9, d10, 0). In real life examples such as Figure 1 the subscript goes up to about one thousand instead of merely to ten.
(10) |
You can think of the matrix as having a horizontal t-axis and a vertical -axis. The 1's in the matrix are arranged on the hyperbola .The transpose matrix defining some from gives synthetic data from the zero-offset (or stack) model , namely,
(11) |
A program for nearest-neighbor normal moveout as defined by
equations (10) and (11)
is nmo0().
Because of the limited alphabet of programming languages,
I used the keystroke z to denote .
subroutine nmo0( adj, add, slow, x, t0, dt, n,zz, tt )
integer it, iz, adj, add, n
real xs, t , z, slow(n), x, t0, dt, zz(n), tt(n)
call adjnull( adj, add, zz,n, tt,n)
do iz= 1, n { z = t0 + dt*(iz-1) # Travel-time depth
xs= x * slow(iz)
t = sqrt ( z * z + xs * xs)
it= 1 + .5 + (t - t0) / dt # Round to nearest neighbor.
if( it <= n )
if( adj == 0 )
tt(it) = tt(it) + zz(iz)
else
zz(iz) = zz(iz) + tt(it)
}
return; end
A program is a ``pull'' program if the loop creating the output covers each location in the output and gathers the input from wherever it may be. A program is a ``push'' program if it takes each input and pushes it to wherever it belongs. Thus this NMO program is a ``pull'' program for doing the model building (data processing), and it is a ``push'' program for the data building. You could write a program that worked the other way around, namely, a loop over t with z found by calculation .What is annoying is that if you want a push program going both ways, those two ways cannot be adjoint to one another.
Normal moveout is a linear operation. This means that data can be decomposed into any two parts, early and late, high frequency and low, smooth and rough, steep and shallow dip, etc.; and whether the two parts are NMO'ed either separately or together, the result is the same. The reason normal moveout is a linear operation is that we have shown it is effectively a matrix multiply operation and that operation fulfills .