Normal-moveoutnormal moveout correction (NMO) is a geometrical correction of reflection seismic data that stretches the time axis so that data recorded at nonzero separation x0 of shot and receiver, after stretching, appears to be at x0=0. NMO correction is roughly like time-to-depth conversion with the equation v2 t2 = z2 + x02. After the data at x0 is stretched from t to z, it should look like stretched data from any other x (assuming these are plane horizontal reflectors, etc.). In practice, z 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. This is called ``stacking'' or ``NMO stacking.'' The adjoint to this operation is to begin from a model which ideally is the zero-offset trace and spray this model to all offsets. From a matrix viewpoint, stacking is like a row vector of normal moveout operators and modeling is like a column. An example is shown in Figure .
Figure 7 Hypothetical model, synthetic data, and model image.
A module that does reverse moveout is hypotenusei. Given a zero-offset trace, it makes another at non-zero offset. The adjoint does the usual normal moveout correction. hypotenuseiinverse moveout (My 1992 textbook (PVI) illustrates many additional features of normal moveout.) 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. imosprayinverse NMO spray
This is the first time we have built an operator (moveout and stack) from a collection of other operators (moveout at various offsets) and there are new possibilities for confusion and program bugs. As earlier with the matrix multiplication operator, to use the imospray operator, there are two steps, one that we use to set things up
call imospray_init( slow, x0,dx, t0,dt, nt,nx)and another step that we use a lot in the next chapter for analysis and data fitting.
stat = imospray_lop( adj, add, stack, gather)Later we'll see programs that are not operators. Every program that is an operator (contains #% _init and #% _lop) is expanded by Loptran to a longer Fortran code where the _lop function begins by (potentially) erasing the output (when add=.false.). This potential erasing is done in both hypotenusei and imospray. Consider the the adjoint of spraying which is stacking. Here the occurance of the add=.true. in imospray assures we do not erase the stack each time we add in another trace. Because of Loptran we don't explicitly see that imospray_lop has its own potential erase of its output which we'd turn off if we wanted to add one stack upon another.