    Basic operators and adjoints  Next: Coding chains and arrays Up: FAMILIAR OPERATORS Previous: Smoothing with box and

## Nearest-neighbor normal moveout (NMO)

Normal-moveout correction is a geometrical correction of reflection seismic data that stretches the time axis so that data recorded at nonzero separation of shot and receiver, after stretching, appears to be at . NMO correction is roughly like time-to-depth conversion with the equation . After the data at is stretched from to , it should look like stretched data from any other (assuming these are plane horizontal reflectors, etc.). In practice, is not used; rather, traveltime depth is used, where ; so . (Because of the limited alphabet of programming languages, I often use the keystroke z to denote .)

Typically, many receivers record each shot. Each seismogram can be transformed by NMO and the results all added. The whole process is called NMO stacking.'' The adjoint to this operation is to begin from a model that ideally is the zero-offset trace, and spray this model to all offsets. From a matrix viewpoint, stacking is like a row vector of NMO operators, and modeling is like a column. An example is shown in Figure 8.

cunha
Figure 8.
Hypothetical model, synthetic data, and model image.    A module that does reverse moveout is hypotenusei. Given a zero-offset trace, it makes another at nonzero offset. The adjoint does the usual normal moveout correction.

user/gee/hypotenusei.c
 void hypotenusei_set(float t0 /* time origin */, float dt /* time sampling */, float xs /* offset times slowness */) /*< set up >*/ { int it; float t, z2; for (it=0; it < nt; it++) { t = t0 + dt*it; z2 = t * t - xs * xs; iz[it] = ( z2 >= 0.)? 0.5 + (sqrtf(z2) - t0) /dt: -1; } } void hypotenusei_lop(bool adj, bool add, int n1, int n2, float *zz, float *tt) /*< linear operator >*/ { int it; sf_adjnull(adj,add,n1,n2,zz,tt); for (it=0; it < nt; it++) { if (iz[it] < 0) continue; if (adj) zz[iz[it]] += tt[it]; else tt[it] += zz[iz[it]]; } } 
My 1992 textbookPVI (Earth Soundings Analysis : Processing Versus Inversion) illustrates many additional features of NMO. A companion routine imospray loops over offsets and makes a trace for each. The adjoint of imospray is the industrial process of moveout and stack.
user/gee/imospray.c
 void imospray_lop(bool adj, bool add, int n1, int n2, float *stack, float *gather) /*< linear operator >*/ { int ix; float x; sf_adjnull(adj,add,n1,n2,stack,gather); for (ix=0; ix < nx; ix++) { x = x0 + dx*ix; hypotenusei_set (t0, dt, x); hypotenusei_lop (adj, true, nt, nt, stack, gather+ix*nt); } }    Basic operators and adjoints  Next: Coding chains and arrays Up: FAMILIAR OPERATORS Previous: Smoothing with box and

2014-09-27