full-waveform inversion using seislet regularizationahay.org/rsf/book/tccs/fwiseislet/paper.pdf ·...

12
1 Full-waveform inversion using seislet regularization a a Published in Geophysics, 82, no. 5, A43-A49, (2017) Zhiguang Xue 1 , Hejun Zhu 2 and Sergey Fomel 1 ABSTRACT Because of inaccurate, incomplete and inconsistent waveform records, full waveform inversion (FWI) in the framework of local optimization approach may not have a unique solution and thus remains an ill-posed inverse problem. To improve the robustness of FWI, we present a new model regularization approach, which enforces the sparsity of solutions in the seislet domain. The construction of seislet basis functions requires structural information, which can be estimated iteratively from migration images. We implement FWI with seislet regularization using nonlinear shaping regularization, and impose sparseness by applying soft thresholding on the updated model in the seislet domain at each iteration of the data fitting process. The main extra computational cost of the method relative to standard FWI is the cost of applying forward and inverse seislet transforms at each iteration. This cost is almost negligible compared to the cost of solving wave equations. Numerical tests using the synthetic Marmousi model demonstrate that seislet regularization can greatly improve the robustness of FWI by recovering high-resolution velocity models, particularly in the presence of strong crosstalk artifacts from simultaneous sources or strong random noise in the data. INTRODUCTION Full waveform inversion (FWI) is a data-fitting procedure used to construct high-resolution quantitative subsurface models by exploiting full information in observed data (Lailly, 1983; Tarantola, 1984; Virieux and Operto, 2009). However, the problem is inherently ill-posed, and suffers from artifacts that could be falsely interpreted as “geological structures”. One way to mitigate this problem is by adding regularization or preconditioning to guide the inversion toward a model consistent with a priori geological or geophysical constraints. The choice among different regularization techniques depends on the specific problem, and can be governed by the need to preserve or emphasize particular desired features of the model (Loris et al., 2007). For example, if one is mostly interested in large-scale features, it is natural to introduce a regularizing constraint or penalty term involving spatial derivatives. On the other hand, if one seeks to find solutions that are sparse with respect to a given basis, this can be achieved by imposing a sparsity constraint involving appropriate transforms such as Fourier, wavelet or curvelet transforms (Loris et al., 2007). This regularization 1 Parts of this paper were presented at 2015 SEG Annual Meeting

Upload: ngodieu

Post on 19-Mar-2018

228 views

Category:

Documents


2 download

TRANSCRIPT

  • 1

    Full-waveform inversion using seislet regularizationa

    aPublished in Geophysics, 82, no. 5, A43-A49, (2017)

    Zhiguang Xue1, Hejun Zhu2 and Sergey Fomel1

    ABSTRACT

    Because of inaccurate, incomplete and inconsistent waveform records, full waveforminversion (FWI) in the framework of local optimization approach may not have a uniquesolution and thus remains an ill-posed inverse problem. To improve the robustness ofFWI, we present a new model regularization approach, which enforces the sparsity ofsolutions in the seislet domain. The construction of seislet basis functions requiresstructural information, which can be estimated iteratively from migration images. Weimplement FWI with seislet regularization using nonlinear shaping regularization, andimpose sparseness by applying soft thresholding on the updated model in the seisletdomain at each iteration of the data fitting process. The main extra computationalcost of the method relative to standard FWI is the cost of applying forward and inverseseislet transforms at each iteration. This cost is almost negligible compared to thecost of solving wave equations. Numerical tests using the synthetic Marmousi modeldemonstrate that seislet regularization can greatly improve the robustness of FWIby recovering high-resolution velocity models, particularly in the presence of strongcrosstalk artifacts from simultaneous sources or strong random noise in the data.

    INTRODUCTION

    Full waveform inversion (FWI) is a data-fitting procedure used to construct high-resolutionquantitative subsurface models by exploiting full information in observed data (Lailly, 1983;Tarantola, 1984; Virieux and Operto, 2009). However, the problem is inherently ill-posed,and suffers from artifacts that could be falsely interpreted as geological structures. Oneway to mitigate this problem is by adding regularization or preconditioning to guide theinversion toward a model consistent with a priori geological or geophysical constraints. Thechoice among different regularization techniques depends on the specific problem, and canbe governed by the need to preserve or emphasize particular desired features of the model(Loris et al., 2007). For example, if one is mostly interested in large-scale features, it isnatural to introduce a regularizing constraint or penalty term involving spatial derivatives.On the other hand, if one seeks to find solutions that are sparse with respect to a given basis,this can be achieved by imposing a sparsity constraint involving appropriate transformssuch as Fourier, wavelet or curvelet transforms (Loris et al., 2007). This regularization

    1Parts of this paper were presented at 2015 SEG Annual Meeting

  • Xue et al. 2 FWI with seislet regularization

    procedure finds solutions that are faithfully represented by a relatively small number ofnon-zero coefficients in the transformed domain.

    We propose to impose sparsity regularization on the model in the seislet domain (Fomeland Liu, 2010) to improve the robustness of FWI. We refer to this regularization as seisletregularization. A model in the seislet domain is expressed using basis functions aligned alonglocally planar structures. Other researchers have previously used the sparsity of velocitymodel in other transform domains for velocity model building. For instance, Loris et al.(2007) applied l1-norm regularization in a wavelet basis to solve global seismic tomographyproblems, allowing for the possibility of sharp discontinuities superimposed on a smoothlyvarying background model. Li et al. (2012) computed the model updates from randomsubsets of data and used curvelet domain sparsity promotion to suppress crosstalk betweendifferent sources. Curvelets are appropriate for seismic data because they provide a provablyoptimal decomposition of wave-propagation operators (Candes and Demanet, 2005). Inthis paper, the sparsity regularization for velocity model is implemented by imposing a softthresholding on the updated model in the seislet domain. Compared to other transformdomains, seislets exhibit a superior data compression and sparsity for events with dominantlocal slopes (Chen et al., 2016). The classic digital wavelet transform is equivalent to seislettransform with the erroneous zero slope (Fomel and Liu, 2010).

    Seislet regularization allows us to build a model that both fits the data and has astrong tendency to be sparse in the seislet basis. Because seislet basis functions are alignedalong locally planar structures, this helps to attenuate random noise and build geologically-consistent models. Different approaches to generating geologically sensible models for seis-mic inversion have been proposed before. Guitton et al. (2012) used directional Laplacianfilter as model preconditioning operator in FWI to smooth gradients along geological dips.Ma et al. (2012) proposed to invert for a sparse velocity model in FWI, and connected thesparse and dense models through image-guided interpolation. Xue et al. (2016) incorpo-rated linear shaping regularization (Fomel, 2007) into least-squares reverse-time migration(RTM) and used structure-enhancing filtering to mitigate artifacts caused by simultaneous-source or incomplete data. Compared to these methods, the proposed method offers analternative formulation with a highly efficient implementation. It is formulated as the spar-sity constraint on the model in the seislet domain, and is implemented by imposing a softthresholding on the updated model at each iteration.

    In this paper, we first introduce FWI with and without seislet regularization, and illus-trate their implementation differences. Next, we use two numerical examples to verify theeffectiveness of the proposed method in improving the robustness of FWI by suppressingartifacts caused by encoded data and random noise. Both examples are based on the 2DMarmousi synthetic model (Bourgeois et al., 1991).

    THEORY

    The objective function of standard FWI can be written as

    J(m) =12||dobs F(m)||22 , (1)

    where m is the velocity model, dobs is the observed waveform data and F stands for thenonlinear forward modeling operator.

  • Xue et al. 3 FWI with seislet regularization

    A popular local optimization algorithm for minimizing this function is based on thenonlinear conjugate-gradient method (Mora, 1987; Tarantola, 1987), where the model isupdated at the iteration n in the direction of sn, which is a linear combination of the gradientat iteration n, J(mn), and the previous conjugate direction sn1. This optimizationscheme can be formulated as follows:

    mn+1 = mn + nsn , sn = J(mn) + nsn1 , (2)

    where scalar n can be obtained by perfoming a line search and n is designed to guaranteethat sn and sn1 are conjugate.

    We propose to apply nonlinear shaping regularization (Fomel, 2008) to impose sparsenessof the velocity model in the seislet domain and modify the iteration process in equation 2as follows:

    mn+1 = S1TS(mn + nsn) , (3)

    where S1 and S stand for the inverse and forward seislet transforms, respectively. T isthe soft thresholding operator and has the following function expression:

    T (x) =

    x t , x > t0 , |x| tx+ t , x < t

    (4)

    where t is a positive threshold level. If seislet transform were an unitary operator, theiteration process in equation 3 would be equivalent to using linearized Bregman iteration(Yin et al., 2008; Cai et al., 2009) to minimize the following objective function:

    J(m) =12||dobs F(m)||22 + ||Sm||1 , (5)

    where is a regularization parameter.

    The difference of equation 3 to the iterative scheme described by equation 2 is that thenew scheme involves a model shaping operator, which is the combination of inverse seislettransform, soft thresholding operator and forward seislet transform. The purpose of theshaping operator S1TS is to remove possible artifacts existing in the updated model andto gradually achieve a geologically meaningful model. In implementation of equation 3, steplength n is estimated by line search without including the shaping operator, and we applythe shaping operator to the updated model after line search to get the new model mn+1.In this way, we just use the shaping operator once at each iteration.

    Seislet transform requires the input of local slope, because in the seislet domain, themodel is represented by the basis functions that are aligned with local structures. Figure 1shows a simple test to check the properties of velocity model in the seislet domain. Wecompare seislet coefficients and basis functions with those of the digital wavelet transform,using the Marmousi model (Figure 1a). The dip required by seislet transform is directlyestimated from the Marmousi model in this test. Figure 1b and 1c show the Marmousimodel in the wavelet and seislet domain, respectively. We observe that the non-zero seisletcoefficients focus at coarse scales but wavelet transform has small residual coefficients at finescales. From this observation, we can conclude that the seislet transform has a better datacompression and sparsity than the wavelet transform, which is further verified by Figure 1d,

  • Xue et al. 4 FWI with seislet regularization

    where a significantly faster decay of the seislet coefficients is evident. Figure 1e and 1f showsome randomly selected representative basis functions for wavelet and seislet transforms,respectively. We can observe that the direction of seislet basis functions follows structuraldirection, while the wavelet basis functions correspond to zero slope.

    (a) (b)

    (c) (d)

    (e) (f)

    Figure 1: Coefficients and basis functions of wavelet and seislet transforms for the Marmousimodel. (a) The exact Marmousi model; (b) model in the wavelet domain; (c) model in theseislet domain; (d) transform coefficients sorted from large to small, normalized, and plottedon a decibel scale; (e) and (f) randomly selected representative basis functions for waveletand seislet transforms, respectively.

    EXAMPLES

    Experiment setup

    We use the classic 2D Marmousi model (Bourgeois et al., 1991) to test the effectiveness ofthe proposed method. The model was first subsampled from 2301751 cells at 4 m cell size

    from rsf.proj import *import random, string, math

    random.seed(2005)

    def rnd1(x):r=str(random.randint(1,188))return r

    def rnd2(x):r=str(random.randint(1,512))return r

    def plotmodel(title):return '''grey color=j scalebar=y bias=2.5barlabel=Velocity barunit=km/s barreverse=ylabelsz=9 labelfat=3 titlesz=9 titlefat=3screenratio=0.5 title="%s"''' %title

    def plotdip(title):return '''grey color=j scalebar=ybarlabel=Dip barunit= barreverse=nlabelsz=9 labelfat=3 titlesz=9 titlefat=3screenratio=0.5 title="%s"''' %title

    SConscript('../timedomain/SConstruct')

    # Velocitymarm='../timedomain/marm.rsf'Flow('marm',marm,'cp')Result('marm',plotmodel(''))

    # Initial modelFlow('init','marm','smooth rect1=20 rect2=50 repeat=3')Result('init',plotmodel(''))

    # Estimate dipFlow('dip','marm','dip rect1=10 rect2=10 order=1')Result('dip',plotdip(''))

    # Seislet and Wavelet comparisonFlow('seislet','marm dip','''seislet dip=${SOURCES[1]} eps=0.1 adj=y inv=y unit=y type=b ''')Result('seislet','put o2=0 d2=1 unit2= unit1=km o1=0 d1=0.016|grey pclip=99.5 label1=Depth label2=Scale screenratio=0.5 title= color=j labelsz=9 labelfat=3 titlesz=9 titlefat=3')

    Flow('wavelet','marm','''transp |dwt inv=y adj=n |transp ''')Result('wavelet','put o2=0 d2=1 unit2= unit1=km o1=0 d1=0.016|grey pclip=99.5 label1=Depth label2=Scale screenratio=0.5 title= color=j labelsz=9 labelfat=3 titlesz=9 titlefat=3')

    Flow('seicoef','seislet','put n1=96256 o1=1 d1=1 n2=1 unit1= unit2= |sort')Flow('wavcoef','wavelet','put n1=96256 o1=1 d1=1 n2=1 unit1= unit2= |sort')Result('coefs','seicoef wavcoef','''cat axis=2 ${SOURCES[1:2]} |window n1=30000 |scale axis=1 |math output="10*log(input)/log(10)" |graph dash=0,1 label1="Number of Samples" label2=Magnitudeunit2="dB" title= screenratio=0.5 wherexlabel=t plotfat=4labelsz=9 labelfat=3 titlesz=9 titlefat=3''')Plot('labels',None,'box x0=5 y0=4.2 label="Seislet" xt=0.5 yt=0.5')Plot('labelw',None,'box x0=7.6 y0=7.1 label="Wavelet" xt=0.5 yt=0.5')Result('comparison','Fig/coefs labels labelw','Overlay')

    Flow('marmsei','marm dip','''seislet dip=${SOURCES[1]} eps=0.1 adj=y inv=y unit=y type=b |threshold pclip=5 |seislet dip=${SOURCES[1]} eps=0.1 inv=y unit=y type=b''')Result('marmsei',plotmodel(''))

    Flow('marmwav','marm','''transp |dwt inv=y adj=n |transp |threshold pclip=5 |transp |dwt inv=y adj=y |transp''')Result('marmwav',plotmodel(''))

    # Randomly selected representative basis functions for wavelet and seislet transformsnsp=500k1=string.join(map(rnd1,range(nsp)),',')k2=string.join(map(rnd2,range(nsp)),',')

    Flow('spikes',None,'spike nsp=%d k1=%s k2=%s n1=188 n2=512 o2=0 d2=0 d1=0.016 d2=0.016 label1=Depth unit1=km' %(nsp,k1,k2),stdin=0)Result('marm-spike','spikes','smooth rect1=2 rect2=2 |grey pclip=100 screenratio=0.5 title= labelsz=9 labelfat=3 titlesz=9 titlefat=3')

    Result('imps','spikes dip','seislet dip=${SOURCES[1]} eps=0.1 inv=y |grey screenratio=0.5 title= labelsz=9 labelfat=3 titlesz=9 titlefat=3 pclip=97')Result('impw','spikes dip','transp| dwt eps=0.2 adj=y inv=y unit=y type=b|transp|grey screenratio=0.5 title= labelsz=9 labelfat=3 titlesz=9 titlefat=3 pclip=97')

    End()

  • Xue et al. 5 FWI with seislet regularization

    (a) (b)

    Figure 2: (a) Initial model and (b) one shot record for true model with xs = 4km.

    to 512188 cells at 16 m cell size, as shown in Figure 1a. Figure 2a shows the initial modelfor FWI, obtained by smoothing the target model. A fixed-spread surface acquisition isused, involving 32 sources located at every 240 m. A Ricker wavelet with center frequencyof 13 Hz is used to generate the synthetic data. Figure 2b shows a shot record with sourcelocation at 4 km. We perform frequency-domain FWI using the fast Helmholtz solver (Liet al., 2014). We used 8 frequencies ranging from 4 to 11 Hz and carried out 10 iterationsfor each frequency. We perform two tests: one with encoded data and the other one withnoisy data.

    Dip estimation

    Before we conduct the FWI with seislet regularization, we need to provide local-dip infor-mation for the seislet transform. We estimate the local dip from the RTM image usingplane-wave destruction (Fomel, 2002). The dip estimation is computationally inexpensivecompared to RTM. With the initial velocity, we can get an initial RTM image as shown inFigure 3a. Though some structures of the image appear at wrong locations, we can get anacceptable local dip map (Figure 3b). We use this initially estimated dip to perform thefirst 30 iterations (for the first 3 frequencies). After we finish the iterations at 6 Hz, a moreaccurate velocity is obtained, with which we can get a better RTM image. Then we canestimate the second dip for the next 30 iterations (for the frequencies 7-9 Hz). Similarly, wecan perform the third RTM (Figure 3c) after the inversions with 9 Hz frequency, and get amuch better dip (Figure 3d), which is used for the last 20 iterations (for the frequencies 10-11 Hz). Comparing Figure 3a and 3c, we can find that the previous position of structuresin the central and deep parts has been corrected in the new RTM image. Note that weuse un-encoded data to perform RTM in the encoded data test in order to avoid crosstalkartifacts in RTM images. In the noisy data test, the assumed noisy data is used to carryout RTM.

    from rsf.proj import *import math

    def plotmodel(title):return '''grey color=j scalebar=y bias=2.5barlabel=Velocity barunit=km/s barreverse=ylabelsz=9 labelfat=3 titlesz=9 titlefat=3screenratio=0.5 title="%s"''' %title

    # True velocityFetch('marmvel.hh',"marm")Flow('marm','marmvel.hh','''dd form=native |scale rscale=0.001 |put label1=Depth label2=Distance unit1=km unit2=km d1=0.004 d2=0.004|window j1=4 j2=4 |window f2=30 n2=512 |put o2=0''')Result('marm2','marm',plotmodel(''))

    # Initial velocityFlow('init','marm','smooth rect1=20 rect2=50 repeat=3')Result('init2','init',plotmodel(''))

    # Generate wavelet and dataFlow('wavelet',None,'spike n1=4001 d1=0.001 o1=0. k1=150 mag=1e5 |ricker1 frequency=13')Result('wavelet2','wavelet','window n1=400 |graph title= screenratio=0.5')

    Result('spectra','wavelet','spectra |graph min1=0 max1=40 title= screenratio=0.5')Flow('data','marm wavelet','''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} output=$TARGET function=1 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Result('shot15','data','window n3=1 f3=15 |grey title= pclip=98 labelsz=9 labelfat=3 titlesz=9 titlefat=3 screenratio=0.5')

    # Transform wavelet and data to frequency domainFlow('cwavelet','wavelet','fft1')Flow('wreal','cwavelet','window min1=4 n1=8 j1=4 |real')Flow('wimag','cwavelet','window min1=4 n1=8 j1=4 |imag')Flow('creal','wreal','''helm2D_genshot n1=188 d1=0.016 n2=512 d2=0.016 ow=3.95062 dw=0.987656 nw=8ns=32 srcz=3 srcx0=25 srcdx=15fmag=$SOURCE''')Flow('cimag','wimag','''helm2D_genshot n1=188 d1=0.016 n2=512 d2=0.016 ow=3.95062 dw=0.987656 nw=8ns=32 srcz=3 srcx0=25 srcdx=15fmag=$SOURCE''')Flow('csource','creal cimag','cmplx ${SOURCES[1]}')

    Flow('cdata','data','fft1')Flow('dreal','cdata','window min1=4 n1=8 j1=4 |real |pad n4=1 d4=0.016 o4=0.048|transp plane=14 |pad beg1=3 end1=184 |math output="-input"')Flow('dimag','cdata','window min1=4 n1=8 j1=4 |imag |pad n4=1 d4=0.016 o4=0.048|transp plane=14 |pad beg1=3 end1=184 |math output="-input"')Flow('fdata','dreal dimag','cmplx ${SOURCES[1]}')

    # Plot data at 4 and 10 HzFlow('data4','dreal','window n1=1 f1=3 n4=1 f4=0 |transp')Result('data4','grey title= screenratio=0.3 labelsz=9 labelfat=3 titlesz=9 titlefat=3')Flow('data10','dreal','window n1=1 f1=3 n4=1 f4=6 |transp')Result('data10','grey title= screenratio=0.3 labelsz=9 labelfat=3 titlesz=9 titlefat=3')

    # Receiver mapFlow('receiver',None,'helm2D_genrec n1=188 d1=0.016 n2=512 d2=0.016 recz=3 recx0=0 recdx=1')

    # Comparison: confirm the consistencyFlow('blend','marm csource','helm2D_forward source=${SOURCES[1]}')

    Flow('trace1','fdata','real |window n4=1 f4=2 n3=1 f3=15 n1=1 f1=3')Flow('trace2','blend','real |window n4=1 f4=2 n3=1 f3=15 n1=1 f1=3')Result('traces','trace1 trace2','cat axis=2 ${SOURCES[1]} |graph title= label2="Amplitude of Real Part" unit2= labelsz=9 labelfat=3 titlesz=9 titlefat=3 screenratio=0.3')

    # Generate noisy dataFlow('noise','data','noise rep=y range=0.045 var=0.00015 seed=2013 |bandpass flo=2 nplo=1 fhi=20')Result('nspectra','noise','spectra all=y |graph title= label2=Amplitude unit2= wherexlabel=top min1=0 max1=20 labelsz=9 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')Flow('ndata','data noise','add ${SOURCES[1]}')Plot('ndata','grey wanttitle=n',view=1)

    Flow('ncdata','ndata','fft1')Flow('ndreal','ncdata','window min1=4 n1=8 j1=4 |real |pad n4=1 d4=0.016 o4=0.048|transp plane=14 |pad beg1=3 end1=184 |math output="-input"')Flow('ndimag','ncdata','window min1=4 n1=8 j1=4 |imag |pad n4=1 d4=0.016 o4=0.048|transp plane=14 |pad beg1=3 end1=184 |math output="-input"')Flow('nfdata','ndreal ndimag','cmplx ${SOURCES[1]}')

    End()

  • Xue et al. 6 FWI with seislet regularization

    (a) (b)

    (c) (d)

    Figure 3: Dip estimation from migration images. (a) RTM with initial velocity; (b) localdip map estimated from (a), which will be used for the first 30 iterations; (c) third RTMwith updated velocity after 60 iterations (4-9 Hz data); (d) dip map estimated from (c) andused for the last 20 iterations (10-11 Hz data).

    from rsf.proj import *import math

    def plotmodel(title):return '''grey color=j scalebar=y bias=2.5barlabel=Velocity barunit=km/s barreverse=ylabelsz=9 labelfat=3 titlesz=9 titlefat=3screenratio=0.5 title="%s"''' %title

    def plotdip(title):return '''grey color=j scalebar=ybarlabel=Samples barunit= barreverse=nlabelsz=9 labelfat=3 titlesz=9 titlefat=3screenratio=0.5 title="%s"''' %title

    SConscript('../timedomain/SConstruct')

    # Velocitymarm='../timedomain/marm.rsf'Flow('marm',marm,'cp')Result('marm',plotmodel('Exact model'))

    # Initial modelFlow('init','marm','smooth rect1=20 rect2=50 repeat=3')Result('init',plotmodel('Initial model'))

    # Copy datacsource='../timedomain/csource.rsf'Flow('csource',csource,'cp')fdata='../timedomain/fdata.rsf'Flow('fdata',fdata,'cp')receiver='../timedomain/receiver.rsf'Flow('receiver',receiver,'cp')

    # First RTM and Dipdata='../timedomain/data.rsf'Flow('data',data,'cp')wavelet='../timedomain/wavelet.rsf'Flow('wavelet',wavelet,'cp')Flow('rtm1','init wavelet data','''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm12','rtm1','laplac |pow pow1=1.')Result('rtm12','grey title= screenratio=0.5 labelsz=9 labelfat=3 titlesz=9 titlefat=3 scalebar=y')

    Flow('mask','rtm12','math output=1 |cut max1=0.5 |cut max2=0.4 |cut min2=7.8')Flow('dip1','rtm12 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip1',plotdip(''))

    # FWI example with blended data and sparsity constraintnw=8ow=3.95062dw=0.987656niter=10

    model=[]curve=[]oldvel='init'dip='dip1'# loop over frequencyfor iw in range(nw):omega=2*math.pi*(ow+dw*iw)src='src%d' %iwrcd='rcd%d' %iwFlow(src,'csource','window f4=%d n4=1' %iw)Flow(rcd,'fdata','window f4=%d n4=1' %iw)

    # update dipif iw==3:Flow('rtm2',[oldvel,'wavelet','data'],'''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm22','rtm2','laplac |pow pow1=1.')Result('rtm22','grey title= screenratio=0.5 labelsz=9 labelfat=3 titlesz=9 titlefat=3 scalebar=y')Flow('dip2','rtm22 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip2',plotdip(''))dip='dip2'

    if iw==6:Flow('rtm3',[oldvel,'wavelet','data'],'''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm32','rtm3','laplac |pow pow1=1.')Result('rtm32','grey title= screenratio=0.5 labelsz=9 labelfat=3 titlesz=9 titlefat=3 scalebar=y')Flow('dip3','rtm32 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip3',plotdip(''))dip='dip3'# inner loop at each frequencyfor iter in range(niter):

    source='src%d-%d' %(iw,iter)record='rcd%d-%d' %(iw,iter)seed=iw*niter+iter+1Flow([source,record],[src,rcd],'''fwipe encoding=y nsim=4 nsource=8 seed=%doldrec=${SOURCES[1]} newrec=${TARGETS[1]}''' %seed)

    newvel='sevel%d-%d' %(iw,iter)temvel='temvel%d-%d' %(iw,iter)newgrad='grad%d-%d' %(iw,iter)newdir='dir%d-%d' %(iw,iter)misfit='misfit%d-%d' %(iw,iter)

    # Calculate steepest gradientFlow([newgrad,misfit],[oldvel,'receiver',source,record],'''fwigrad misfit=${TARGETS[1]} omega=%greceiver=${SOURCES[1]} source=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Update the conjugate directionif iter == 0:Flow(newdir,newgrad,'math output="-input"')else:Flow(newdir,[olddir,oldgrad,newgrad],'''fwidir grad0=${SOURCES[1]} grad1=${SOURCES[2]} option=p''')

    # Perform a line searchalpha1='alpha1-%d-%d' %(iw,iter)alpha2='alpha2-%d-%d' %(iw,iter)alpha='alpha%d-%d' %(iw,iter)update1='update1-%d-%d' %(iw,iter)update2='update2-%d-%d' %(iw,iter)misfit1='misfit1-%d-%d' %(iw,iter)misfit2='misfit2-%d-%d' %(iw,iter) # Test1Flow(alpha1,None,'math output=0.1 n1=1')Flow(update1,[oldvel,newdir,alpha1],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')Flow(misfit1,[update1,source,'receiver',record],'''fwiobj omega=%g source=${SOURCES[1]}receiver=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Test2Flow(alpha2,None,'math output=0.2 n1=1')Flow(update2,[oldvel,newdir,alpha2],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')Flow(misfit2,[update2,source,'receiver',record],'''fwiobj omega=%g source=${SOURCES[1]}receiver=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Optimal AlphaFlow(alpha,[misfit,misfit1,misfit2],'''math val0=$SOURCE val1=${SOURCES[1]} val2=${SOURCES[2]}output="(val2-4.0*val1+3.0*val0)/(20.0*(val2-2.0*val1+val0))"''')

    # Update modelFlow(temvel,[oldvel,newdir,alpha],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')# Soft thresholding in seislet domainFlow(newvel,[temvel,dip],'''seislet dip=${SOURCES[1]} eps=0.1 adj=y inv=y unit=y type=b |threshold pclip=18 |seislet dip=${SOURCES[1]} eps=0.1 inv=y unit=y type=b |clip2 lower=1.5 upper=5.5''')

    # Pass down...oldvel=newveloldgrad=newgradolddir=newdirPlot(newvel,plotmodel("Model iw=%d iter=%d" %(iw,iter)))model.append(newvel)curve.append(misfit)

    Plot('models',model,'Movie',view=1)Result('securve',curve,'''cat ${SOURCES[1:%d]} axis=1|scale axis=1 |put d1=1 o1=0 |graph label2="Normalized Misfit" unit2= label1=Iterations unit1= title="Data Misfit with Seislet Regularization"''' %len(curve))

    # Model misfitmisfit=[]for i in range(nw):for j in range(niter):mod='sevel%d-%d' %(i,j)fit='fit%d-%d' %(i,j)Flow(fit,[mod,'marm'],'''add scale=1,-1 ${SOURCES[1]} |math output="input*input" |stack axis=0 norm=n''')misfit.append(fit)Flow('semmisfit',misfit,'cat ${SOURCES[1:%d]}' %len(misfit))Result('semmisfit','''window |scale axis=1 |put d1=1 o1=1 |graph label2="Normalized Misfit" unit2= min2=0.7 label1=Iterations unit1= title="Model Misfit with Seislet Regularization"''')

    # Model misfit comparisonFlow('bmmisfit','../blend/bmmisfit.rsf','cp')Flow('emmisfit','../encoding/emmisfit.rsf','cp')Result('encoding-misfit','bmmisfit emmisfit semmisfit','''cat axis=4 ${SOURCES[1:3]}|window |scale axis=1 |put d1=1 o1=1 |graph label2="Normalized Model Misfit" unit2= min2=0.7 label1=Iterations unit1= wanttitle= dash=2,4,0 labelsz=9 labelfat=3 titlesz=9 titlefat=3 screenratio=0.5 plotfat=5 wherexlabel=top''')

    # Plot final modelsFlow('bvel7-9','../blend/bvel7-9.rsf','cp')Flow('evel7-9','../encoding/evel7-9.rsf','cp')Result('bvel7-9',plotmodel(''))Result('evel7-9',plotmodel(''))Result('sevel7-9',plotmodel(''))

    # Plot data samplesFlow('etrace1','rcd2-0','real |window n3=1 f3=0 n1=1 f1=3')Result('etrace1','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')Flow('etrace2','rcd2-0','real |window n3=1 f3=1 n1=1 f1=3')Result('etrace2','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')Flow('etrace3','rcd2-0','real |window n3=1 f3=2 n1=1 f1=3')Result('etrace3','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')Flow('etrace4','rcd2-0','real |window n3=1 f3=3 n1=1 f1=3')Result('etrace4','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')

    End()

  • Xue et al. 7 FWI with seislet regularization

    (a)

    (b)

    (c)

    (d)

    Figure 4: Real part of 6 Hz frequency component data after first dynamic phase encoding.(a) First supershot containing shots with index i that satisfies: i%4 = 1 and 1 i 32; (b)second supershot (i%4 = 2); (c) third supershot (i%4 = 3); (d) fourth supershot (i%4 = 0).

    from rsf.proj import *import math

    def plotmodel(title):return '''grey color=j scalebar=y bias=2.5barlabel=Velocity barunit=km/s barreverse=ylabelsz=9 labelfat=3 titlesz=9 titlefat=3screenratio=0.5 title="%s"''' %title

    def plotdip(title):return '''grey color=j scalebar=ybarlabel=Samples barunit= barreverse=nlabelsz=9 labelfat=3 titlesz=9 titlefat=3screenratio=0.5 title="%s"''' %title

    SConscript('../timedomain/SConstruct')

    # Velocitymarm='../timedomain/marm.rsf'Flow('marm',marm,'cp')Result('marm',plotmodel('Exact model'))

    # Initial modelFlow('init','marm','smooth rect1=20 rect2=50 repeat=3')Result('init',plotmodel('Initial model'))

    # Copy datacsource='../timedomain/csource.rsf'Flow('csource',csource,'cp')fdata='../timedomain/fdata.rsf'Flow('fdata',fdata,'cp')receiver='../timedomain/receiver.rsf'Flow('receiver',receiver,'cp')

    # First RTM and Dipdata='../timedomain/data.rsf'Flow('data',data,'cp')wavelet='../timedomain/wavelet.rsf'Flow('wavelet',wavelet,'cp')Flow('rtm1','init wavelet data','''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm12','rtm1','laplac |pow pow1=1.')Result('rtm12','grey title= screenratio=0.5 labelsz=9 labelfat=3 titlesz=9 titlefat=3 scalebar=y')

    Flow('mask','rtm12','math output=1 |cut max1=0.5 |cut max2=0.4 |cut min2=7.8')Flow('dip1','rtm12 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip1',plotdip(''))

    # FWI example with blended data and sparsity constraintnw=8ow=3.95062dw=0.987656niter=10

    model=[]curve=[]oldvel='init'dip='dip1'# loop over frequencyfor iw in range(nw):omega=2*math.pi*(ow+dw*iw)src='src%d' %iwrcd='rcd%d' %iwFlow(src,'csource','window f4=%d n4=1' %iw)Flow(rcd,'fdata','window f4=%d n4=1' %iw)

    # update dipif iw==3:Flow('rtm2',[oldvel,'wavelet','data'],'''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm22','rtm2','laplac |pow pow1=1.')Result('rtm22','grey title= screenratio=0.5 labelsz=9 labelfat=3 titlesz=9 titlefat=3 scalebar=y')Flow('dip2','rtm22 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip2',plotdip(''))dip='dip2'

    if iw==6:Flow('rtm3',[oldvel,'wavelet','data'],'''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm32','rtm3','laplac |pow pow1=1.')Result('rtm32','grey title= screenratio=0.5 labelsz=9 labelfat=3 titlesz=9 titlefat=3 scalebar=y')Flow('dip3','rtm32 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip3',plotdip(''))dip='dip3'# inner loop at each frequencyfor iter in range(niter):

    source='src%d-%d' %(iw,iter)record='rcd%d-%d' %(iw,iter)seed=iw*niter+iter+1Flow([source,record],[src,rcd],'''fwipe encoding=y nsim=4 nsource=8 seed=%doldrec=${SOURCES[1]} newrec=${TARGETS[1]}''' %seed)

    newvel='sevel%d-%d' %(iw,iter)temvel='temvel%d-%d' %(iw,iter)newgrad='grad%d-%d' %(iw,iter)newdir='dir%d-%d' %(iw,iter)misfit='misfit%d-%d' %(iw,iter)

    # Calculate steepest gradientFlow([newgrad,misfit],[oldvel,'receiver',source,record],'''fwigrad misfit=${TARGETS[1]} omega=%greceiver=${SOURCES[1]} source=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Update the conjugate directionif iter == 0:Flow(newdir,newgrad,'math output="-input"')else:Flow(newdir,[olddir,oldgrad,newgrad],'''fwidir grad0=${SOURCES[1]} grad1=${SOURCES[2]} option=p''')

    # Perform a line searchalpha1='alpha1-%d-%d' %(iw,iter)alpha2='alpha2-%d-%d' %(iw,iter)alpha='alpha%d-%d' %(iw,iter)update1='update1-%d-%d' %(iw,iter)update2='update2-%d-%d' %(iw,iter)misfit1='misfit1-%d-%d' %(iw,iter)misfit2='misfit2-%d-%d' %(iw,iter) # Test1Flow(alpha1,None,'math output=0.1 n1=1')Flow(update1,[oldvel,newdir,alpha1],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')Flow(misfit1,[update1,source,'receiver',record],'''fwiobj omega=%g source=${SOURCES[1]}receiver=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Test2Flow(alpha2,None,'math output=0.2 n1=1')Flow(update2,[oldvel,newdir,alpha2],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')Flow(misfit2,[update2,source,'receiver',record],'''fwiobj omega=%g source=${SOURCES[1]}receiver=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Optimal AlphaFlow(alpha,[misfit,misfit1,misfit2],'''math val0=$SOURCE val1=${SOURCES[1]} val2=${SOURCES[2]}output="(val2-4.0*val1+3.0*val0)/(20.0*(val2-2.0*val1+val0))"''')

    # Update modelFlow(temvel,[oldvel,newdir,alpha],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')# Soft thresholding in seislet domainFlow(newvel,[temvel,dip],'''seislet dip=${SOURCES[1]} eps=0.1 adj=y inv=y unit=y type=b |threshold pclip=18 |seislet dip=${SOURCES[1]} eps=0.1 inv=y unit=y type=b |clip2 lower=1.5 upper=5.5''')

    # Pass down...oldvel=newveloldgrad=newgradolddir=newdirPlot(newvel,plotmodel("Model iw=%d iter=%d" %(iw,iter)))model.append(newvel)curve.append(misfit)

    Plot('models',model,'Movie',view=1)Result('securve',curve,'''cat ${SOURCES[1:%d]} axis=1|scale axis=1 |put d1=1 o1=0 |graph label2="Normalized Misfit" unit2= label1=Iterations unit1= title="Data Misfit with Seislet Regularization"''' %len(curve))

    # Model misfitmisfit=[]for i in range(nw):for j in range(niter):mod='sevel%d-%d' %(i,j)fit='fit%d-%d' %(i,j)Flow(fit,[mod,'marm'],'''add scale=1,-1 ${SOURCES[1]} |math output="input*input" |stack axis=0 norm=n''')misfit.append(fit)Flow('semmisfit',misfit,'cat ${SOURCES[1:%d]}' %len(misfit))Result('semmisfit','''window |scale axis=1 |put d1=1 o1=1 |graph label2="Normalized Misfit" unit2= min2=0.7 label1=Iterations unit1= title="Model Misfit with Seislet Regularization"''')

    # Model misfit comparisonFlow('bmmisfit','../blend/bmmisfit.rsf','cp')Flow('emmisfit','../encoding/emmisfit.rsf','cp')Result('encoding-misfit','bmmisfit emmisfit semmisfit','''cat axis=4 ${SOURCES[1:3]}|window |scale axis=1 |put d1=1 o1=1 |graph label2="Normalized Model Misfit" unit2= min2=0.7 label1=Iterations unit1= wanttitle= dash=2,4,0 labelsz=9 labelfat=3 titlesz=9 titlefat=3 screenratio=0.5 plotfat=5 wherexlabel=top''')

    # Plot final modelsFlow('bvel7-9','../blend/bvel7-9.rsf','cp')Flow('evel7-9','../encoding/evel7-9.rsf','cp')Result('bvel7-9',plotmodel(''))Result('evel7-9',plotmodel(''))Result('sevel7-9',plotmodel(''))

    # Plot data samplesFlow('etrace1','rcd2-0','real |window n3=1 f3=0 n1=1 f1=3')Result('etrace1','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')Flow('etrace2','rcd2-0','real |window n3=1 f3=1 n1=1 f1=3')Result('etrace2','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')Flow('etrace3','rcd2-0','real |window n3=1 f3=2 n1=1 f1=3')Result('etrace3','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')Flow('etrace4','rcd2-0','real |window n3=1 f3=3 n1=1 f1=3')Result('etrace4','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')

    End()

  • Xue et al. 8 FWI with seislet regularization

    (a) (b)

    (c) (d)

    Figure 5: FWI results of encoded data. (a) Standard FWI without phase encod-ing; (b) standard FWI with dynamic phase encoding; (c) FWI using seislet reg-ularization with dynamic phase encoding; (d) normalized model error versus itera-tion for different inversions: (a) (fine dot), (b) (large dash) and (c) (solid line).

    from rsf.proj import *import math

    def plotmodel(title):return '''grey color=j scalebar=y bias=2.5barlabel=Velocity barunit=km/s barreverse=ylabelsz=9 labelfat=3 titlesz=9 titlefat=3screenratio=0.5 title="%s"''' %title

    def plotdip(title):return '''grey color=j scalebar=ybarlabel=Samples barunit= barreverse=nlabelsz=9 labelfat=3 titlesz=9 titlefat=3screenratio=0.5 title="%s"''' %title

    SConscript('../timedomain/SConstruct')

    # Velocitymarm='../timedomain/marm.rsf'Flow('marm',marm,'cp')Result('marm',plotmodel('Exact model'))

    # Initial modelFlow('init','marm','smooth rect1=20 rect2=50 repeat=3')Result('init',plotmodel('Initial model'))

    # Copy datacsource='../timedomain/csource.rsf'Flow('csource',csource,'cp')fdata='../timedomain/fdata.rsf'Flow('fdata',fdata,'cp')receiver='../timedomain/receiver.rsf'Flow('receiver',receiver,'cp')

    # First RTM and Dipdata='../timedomain/data.rsf'Flow('data',data,'cp')wavelet='../timedomain/wavelet.rsf'Flow('wavelet',wavelet,'cp')Flow('rtm1','init wavelet data','''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm12','rtm1','laplac |pow pow1=1.')Result('rtm12','grey title= screenratio=0.5 labelsz=9 labelfat=3 titlesz=9 titlefat=3 scalebar=y')

    Flow('mask','rtm12','math output=1 |cut max1=0.5 |cut max2=0.4 |cut min2=7.8')Flow('dip1','rtm12 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip1',plotdip(''))

    # FWI example with blended data and sparsity constraintnw=8ow=3.95062dw=0.987656niter=10

    model=[]curve=[]oldvel='init'dip='dip1'# loop over frequencyfor iw in range(nw):omega=2*math.pi*(ow+dw*iw)src='src%d' %iwrcd='rcd%d' %iwFlow(src,'csource','window f4=%d n4=1' %iw)Flow(rcd,'fdata','window f4=%d n4=1' %iw)

    # update dipif iw==3:Flow('rtm2',[oldvel,'wavelet','data'],'''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm22','rtm2','laplac |pow pow1=1.')Result('rtm22','grey title= screenratio=0.5 labelsz=9 labelfat=3 titlesz=9 titlefat=3 scalebar=y')Flow('dip2','rtm22 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip2',plotdip(''))dip='dip2'

    if iw==6:Flow('rtm3',[oldvel,'wavelet','data'],'''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm32','rtm3','laplac |pow pow1=1.')Result('rtm32','grey title= screenratio=0.5 labelsz=9 labelfat=3 titlesz=9 titlefat=3 scalebar=y')Flow('dip3','rtm32 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip3',plotdip(''))dip='dip3'# inner loop at each frequencyfor iter in range(niter):

    source='src%d-%d' %(iw,iter)record='rcd%d-%d' %(iw,iter)seed=iw*niter+iter+1Flow([source,record],[src,rcd],'''fwipe encoding=y nsim=4 nsource=8 seed=%doldrec=${SOURCES[1]} newrec=${TARGETS[1]}''' %seed)

    newvel='sevel%d-%d' %(iw,iter)temvel='temvel%d-%d' %(iw,iter)newgrad='grad%d-%d' %(iw,iter)newdir='dir%d-%d' %(iw,iter)misfit='misfit%d-%d' %(iw,iter)

    # Calculate steepest gradientFlow([newgrad,misfit],[oldvel,'receiver',source,record],'''fwigrad misfit=${TARGETS[1]} omega=%greceiver=${SOURCES[1]} source=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Update the conjugate directionif iter == 0:Flow(newdir,newgrad,'math output="-input"')else:Flow(newdir,[olddir,oldgrad,newgrad],'''fwidir grad0=${SOURCES[1]} grad1=${SOURCES[2]} option=p''')

    # Perform a line searchalpha1='alpha1-%d-%d' %(iw,iter)alpha2='alpha2-%d-%d' %(iw,iter)alpha='alpha%d-%d' %(iw,iter)update1='update1-%d-%d' %(iw,iter)update2='update2-%d-%d' %(iw,iter)misfit1='misfit1-%d-%d' %(iw,iter)misfit2='misfit2-%d-%d' %(iw,iter) # Test1Flow(alpha1,None,'math output=0.1 n1=1')Flow(update1,[oldvel,newdir,alpha1],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')Flow(misfit1,[update1,source,'receiver',record],'''fwiobj omega=%g source=${SOURCES[1]}receiver=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Test2Flow(alpha2,None,'math output=0.2 n1=1')Flow(update2,[oldvel,newdir,alpha2],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')Flow(misfit2,[update2,source,'receiver',record],'''fwiobj omega=%g source=${SOURCES[1]}receiver=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Optimal AlphaFlow(alpha,[misfit,misfit1,misfit2],'''math val0=$SOURCE val1=${SOURCES[1]} val2=${SOURCES[2]}output="(val2-4.0*val1+3.0*val0)/(20.0*(val2-2.0*val1+val0))"''')

    # Update modelFlow(temvel,[oldvel,newdir,alpha],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')# Soft thresholding in seislet domainFlow(newvel,[temvel,dip],'''seislet dip=${SOURCES[1]} eps=0.1 adj=y inv=y unit=y type=b |threshold pclip=18 |seislet dip=${SOURCES[1]} eps=0.1 inv=y unit=y type=b |clip2 lower=1.5 upper=5.5''')

    # Pass down...oldvel=newveloldgrad=newgradolddir=newdirPlot(newvel,plotmodel("Model iw=%d iter=%d" %(iw,iter)))model.append(newvel)curve.append(misfit)

    Plot('models',model,'Movie',view=1)Result('securve',curve,'''cat ${SOURCES[1:%d]} axis=1|scale axis=1 |put d1=1 o1=0 |graph label2="Normalized Misfit" unit2= label1=Iterations unit1= title="Data Misfit with Seislet Regularization"''' %len(curve))

    # Model misfitmisfit=[]for i in range(nw):for j in range(niter):mod='sevel%d-%d' %(i,j)fit='fit%d-%d' %(i,j)Flow(fit,[mod,'marm'],'''add scale=1,-1 ${SOURCES[1]} |math output="input*input" |stack axis=0 norm=n''')misfit.append(fit)Flow('semmisfit',misfit,'cat ${SOURCES[1:%d]}' %len(misfit))Result('semmisfit','''window |scale axis=1 |put d1=1 o1=1 |graph label2="Normalized Misfit" unit2= min2=0.7 label1=Iterations unit1= title="Model Misfit with Seislet Regularization"''')

    # Model misfit comparisonFlow('bmmisfit','../blend/bmmisfit.rsf','cp')Flow('emmisfit','../encoding/emmisfit.rsf','cp')Result('encoding-misfit','bmmisfit emmisfit semmisfit','''cat axis=4 ${SOURCES[1:3]}|window |scale axis=1 |put d1=1 o1=1 |graph label2="Normalized Model Misfit" unit2= min2=0.7 label1=Iterations unit1= wanttitle= dash=2,4,0 labelsz=9 labelfat=3 titlesz=9 titlefat=3 screenratio=0.5 plotfat=5 wherexlabel=top''')

    # Plot final modelsFlow('bvel7-9','../blend/bvel7-9.rsf','cp')Flow('evel7-9','../encoding/evel7-9.rsf','cp')Result('bvel7-9',plotmodel(''))Result('evel7-9',plotmodel(''))Result('sevel7-9',plotmodel(''))

    # Plot data samplesFlow('etrace1','rcd2-0','real |window n3=1 f3=0 n1=1 f1=3')Result('etrace1','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')Flow('etrace2','rcd2-0','real |window n3=1 f3=1 n1=1 f1=3')Result('etrace2','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')Flow('etrace3','rcd2-0','real |window n3=1 f3=2 n1=1 f1=3')Result('etrace3','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')Flow('etrace4','rcd2-0','real |window n3=1 f3=3 n1=1 f1=3')Result('etrace4','graph title= label1=Receiver unit1=km label2="Amplitude of Real Part" unit2= wherexlabel=top labelsz=12 labelfat=3 titlesz=9 titlefat=3 screenratio=0.25 plotfat=4')

    End()

  • Xue et al. 9 FWI with seislet regularization

    Encoded data test

    To reduce the computational burden, one well-known technique is to build supershots by as-sembling several sources, which can reduce the computational cost by a factor roughly equalto the number of sources assembled together (Morton and Ober, 1998; Romero et al., 2000).However, the source-combination technique may introduce crosstalk noise arising from theinterference of waves generated at spatially adjacent sources. To remove the unwantedcrosstalk noise, the blended data is typically paired with phase encoding strategies; amongthem, dynamic phase encoding (Krebs et al., 2009; Baumstein et al., 2011; Ben-Hadj-Aliet al., 2011) is a particularly effective approach. Dynamic phase encoding in frequency-domain FWI involves changing encoding code and building a new encoded superset at eachiteration of each frequency inversion (Ben-Hadj-Ali et al., 2011).

    In this test, we combine every 8 equidistant shots in one supershot, creating 4 supershotsin total. The first supershot contains shots with indices: 1, 5, 9, 13, 17, 21, 25 and 29. Weperform three inversions. The first inversion is the standard FWI with the blended datawithout phase encoding, which means that data are directly blended together without anydesigned codes. The second inversion is the standard FWI with the dynamic phase encodingtechnique, and at each iteration, a new encoding code is generated to build a new superdataset. The encoding code used in this study is the simple phase function ei , where is arandom number in [0, 2]. Figure 4 shows the real part of the 4 encoded supershots at thefirst iteration of the 6 Hz frequency data inversion. From each supershot, we can roughlyobserve 8 large peaks and troughs, and their locations correspond to that of the originalsources. The third inversion inverts the dynamic phase encoded data by using FWI withseislet regularization. We set the soft thresholding parameter in the seislet regularizationempirically to be 18%, meaning that 82% smaller seislet coefficients get removed at eachiteration.

    Figure 5 shows the final results of the three inversions. All the results were obtainedafter 80 iterations. The result of standard FWI without phase encoding contains visiblecrosstalk artifacts, and the model is blurred by noise. Dynamic phase encoding can effec-tively suppress some of the artifacts, but there are some remaining artifacts. As shown byFigure 5c, seislet regularization leads to a noise-free and high-resolution model. Becausethis is a synthetic data inversion test, we can also display the evolution of model misfits. Asshown in Figure 5d, FWI with seislet regularization has a faster model convergence rate.

    Noisy data test

    To further test the robustness of the proposed method, we generate a noisy dataset bysimply adding strong random noise to the original time domain data. Then we transformthe noisy data to frequency domain for inversion. We perform two inversions: standardFWI and FWI using seislet regularization, and compare their results in Figures 6a and 6b.In this comparison, we find that seislet regularization suppresses the noise caused by theambient noise in the data, and helps to get a good inversion result. Figure 6c shows themodel convergence curves, which also tell us that FWI using seislet regularization has afaster model convergence rate. Finally, we show the data convergence of FWI using seisletregularization for each frequency inversion in Figure 6d. We can observe that at eachseparate frequency, the proposed method exhibits a fast data-fitting convergence.

  • Xue et al. 10 FWI with seislet regularization

    (a) (b)

    (c) (d)

    Figure 6: FWI results of noisy data. (a) Standard FWI; (b) FWI with seislet regularization;(c) normalized model error versus iteration for standard FWI (dot line) and FWI with seisletregularization (solid line); (d) data convergence of FWI using seislet regularization at eachfrequency.

    from rsf.proj import *import math

    def plotmodel(title):return '''grey color=j scalebar=y bias=2.5barlabel=Velocity barunit=km/s barreverse=ylabelsz=9 labelfat=3 titlesz=9 titlefat=3screenratio=0.5 title="%s"''' %title

    SConscript('../timedomain/SConstruct')

    # Velocitymarm='../timedomain/marm.rsf'Flow('marm',marm,'cp')Result('marm',plotmodel('Exact model'))

    # Initial modelFlow('init','marm','smooth rect1=20 rect2=50 repeat=3')Result('init',plotmodel('Initial model'))

    # Copy datacsource='../timedomain/csource.rsf'Flow('csource',csource,'cp')fdata='../timedomain/nfdata.rsf'Flow('nfdata',fdata,'cp')receiver='../timedomain/receiver.rsf'Flow('receiver',receiver,'cp')

    # First RTM and Dipdata='../timedomain/ndata.rsf'Flow('ndata',data,'cp')wavelet='../timedomain/wavelet.rsf'Flow('wavelet',wavelet,'cp')Flow('rtm1','init wavelet ndata','''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm12','rtm1','laplac |pow pow1=1.')Result('rtm12','grey title= screenratio=0.5')

    Flow('mask','rtm12','math output=1 |cut max1=0.5 |cut max2=0.4 |cut min2=7.8')Flow('dip1','rtm12 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip1','grey color=j title=Slope scalebar=y screenratio=0.5')

    # FWI example with noisy data and sparsity constraintnw=8ow=3.95062dw=0.987656niter=10

    model=[]curve=[]oldvel='init'dip='dip1'# loop over frequencyfor iw in range(nw):omega=2*math.pi*(ow+dw*iw)src='src%d' %iwrcd='rcd%d' %iwFlow(src,'csource','window f4=%d n4=1' %iw)Flow(rcd,'nfdata','window f4=%d n4=1' %iw)

    # Calculate second dipif iw==3:Flow('rtm2',[oldvel,'wavelet','ndata'],'''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm22','rtm2','laplac |pow pow1=1.')Result('rtm22','grey title= screenratio=0.5')Flow('dip2','rtm22 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip2','grey color=j title=Slope scalebar=y screenratio=0.5')dip='dip2'

    if iw==6:Flow('rtm3',[oldvel,'wavelet','ndata'],'''mpisfwi Fvel=$SOURCE Fwavelet=${SOURCES[1]} Fdat=${SOURCES[2]} output=$TARGET function=3 verb=nnb=100 coef=0.002 nr=512 dr=0.016 r0=0. rz=3 ns=32 ds=0.24 s0=0.4 sz=3 frectx=1 frectz=1''',np=16)Flow('rtm32','rtm3','laplac |pow pow1=1.')Result('rtm32','grey title= screenratio=0.5')Flow('dip3','rtm32 mask','fdip mask=${SOURCES[1]} rect1=10 rect2=10 order=1')Result('dip3','grey color=j title=Slope scalebar=y screenratio=0.5')dip='dip3'

    # inner loop at each frequencyfor iter in range(niter):

    source='src%d-%d' %(iw,iter)record='rcd%d-%d' %(iw,iter)Flow([source,record],[src,rcd],'''fwipe encoding=n nsim=32 nsource=1oldrec=${SOURCES[1]} newrec=${TARGETS[1]}''')

    newvel='snvel%d-%d' %(iw,iter)temvel='temvel%d-%d' %(iw,iter)newgrad='grad%d-%d' %(iw,iter)newdir='dir%d-%d' %(iw,iter)misfit='misfit%d-%d' %(iw,iter)

    # Calculate steepest gradientFlow([newgrad,misfit],[oldvel,'receiver',source,record],'''fwigrad misfit=${TARGETS[1]} omega=%greceiver=${SOURCES[1]} source=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Update the conjugate directionif iter == 0:Flow(newdir,newgrad,'math output="-input"')else:Flow(newdir,[olddir,oldgrad,newgrad],'''fwidir grad0=${SOURCES[1]} grad1=${SOURCES[2]} option=p''')

    # Perform a line searchalpha1='alpha1-%d-%d' %(iw,iter)alpha2='alpha2-%d-%d' %(iw,iter)alpha='alpha%d-%d' %(iw,iter)update1='update1-%d-%d' %(iw,iter)update2='update2-%d-%d' %(iw,iter)misfit1='misfit1-%d-%d' %(iw,iter)misfit2='misfit2-%d-%d' %(iw,iter) # Test1Flow(alpha1,None,'math output=0.1 n1=1')Flow(update1,[oldvel,newdir,alpha1],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')Flow(misfit1,[update1,source,'receiver',record],'''fwiobj omega=%g source=${SOURCES[1]}receiver=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Test2Flow(alpha2,None,'math output=0.2 n1=1')Flow(update2,[oldvel,newdir,alpha2],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')Flow(misfit2,[update2,source,'receiver',record],'''fwiobj omega=%g source=${SOURCES[1]}receiver=${SOURCES[2]} record=${SOURCES[3]}''' %omega)

    # Optimal AlphaFlow(alpha,[misfit,misfit1,misfit2],'''math val0=$SOURCE val1=${SOURCES[1]} val2=${SOURCES[2]}output="(val2-4.0*val1+3.0*val0)/(20.0*(val2-2.0*val1+val0))"''')

    # Update modelFlow(temvel,[oldvel,newdir,alpha],'''fwiupdate direction=${SOURCES[1]} alpha=${SOURCES[2]} max=1''')# Soft thresholding in seislet domainFlow(newvel,[temvel,dip],'''seislet dip=${SOURCES[1]} eps=0.1 adj=y inv=y unit=y type=b |threshold pclip=15 |seislet dip=${SOURCES[1]} eps=0.1 inv=y unit=y type=b |clip2 lower=1.5 upper=5.5''')

    # Pass down...oldvel=newveloldgrad=newgradolddir=newdirPlot(newvel,plotmodel("Model iw=%d iter=%d" %(iw,iter)))model.append(newvel)curve.append(misfit)

    Plot('models',model,'Movie',view=1)# Data misfitResult('sncurve',curve,'''cat ${SOURCES[1:%d]} axis=1|put d1=1 o1=0 |graph label2="Data Misfit" unit2= label1=Iterations unit1= title=labelsz=9 labelfat=3 titlesz=9 titlefat=3 screenratio=0.5 plotfat=5 wherexlabel=top''' %len(curve))

    # Model misfitmisfit=[]for i in range(nw):for j in range(niter):mod='snvel%d-%d' %(i,j)fit='fit%d-%d' %(i,j)Flow(fit,[mod,'marm'],'''add scale=1,-1 ${SOURCES[1]} |math output="input*input" |stack axis=0 norm=n''')misfit.append(fit)Flow('snmmisfit',misfit,'cat ${SOURCES[1:%d]}' %len(misfit))Result('snmmisfit','''window |scale axis=1 |put d1=1 o1=1 |graph label2="Normalized Misfit" unit2= min2=0.7 label1=Iterations unit1= title="Model Misfit with Seislet Regularization"''')

    # Model misfit comparisonFlow('nmmisfit','../noise/nmmisfit.rsf','cp')Result('noise-misfit','nmmisfit snmmisfit','''cat axis=4 ${SOURCES[1:2]}|window |scale axis=1 |put d1=1 o1=1 |graph label2="Normalized Model Misfit" unit2= min2=0.8 label1=Iterations unit1= wanttitle= dash=2,0 labelsz=9 labelfat=3 titlesz=9 titlefat=3 screenratio=0.5 plotfat=5 wherexlabel=top''')

    # Final model comparisonFlow('nvel7-9','../noise/nvel7-9.rsf','cp')Result('nvel7-9',plotmodel(''))Result('snvel7-9',plotmodel(''))

    End()

  • Xue et al. 11 FWI with seislet regularization

    CONCLUSIONS

    With the observation that velocity models with planar structures appear sparse in the seisletdomain, we introduce a sparsity regularization scheme with seislet transform to improve therobustness of FWI and to recover a noise-free, geologically-consistent velocity model. Weimplement this seislet regularization by imposing soft thresholding on the updated modelin the seislet domain at each iteration. We estimate the dip needed by the seislet transformfrom the migration image generated during the iterative inversion. Two numerical testsverify the effectiveness of FWI using seislet regularization.

    ACKNOWLEDGMENTS

    We thank the associate editor J. Rickett and an anonymous reviewer for providing valuablesuggestions. We thank the sponsors of the Texas Consortium for Computational Seismology(TCCS) for financial support. The first author was additionally supported by the StatoilFellows Program at The University of Texas at Austin. All computations presented in thispaper are reproducible using the Madagascar software package (Fomel et al., 2013).

    REFERENCES

    Baumstein, A., W. Ross, and S. Lee, 2011, Simultaneous source elastic inversion of surfacewaves: 73rd Conference and Exhibition, EAGE, Extended Abstracts, C040.

    Ben-Hadj-Ali, H., S. Operto, and J. Virieux, 2011, An efficient frequency-domain full wave-form inversion method using simultaneous encoded sources: Geophysics, 76, no. 4, R109R124.

    Bourgeois, A., M. Bourget, P. Lailly, M. Poulet, P. Ricarte, and R. Versteeg, 1991, Mar-mousi, model and data, in P. Lailly and R. Versteeg, eds., The Marmousi experience:52nd EAGE Meeting, Proceedings of the Workshop on the Practical Aspects of SeismicData Inversion, 516.

    Cai, J. F., S. Osher, and Z. Shen, 2009, Linearized bregman iterations for compressedsensing: Mathematics of Computation, 78, 15151536.

    Candes, E. J., and L. Demanet, 2005, The curvelet representation of wave propagations isoptimally sparse: Communications on Pure and Applied Mathematics, 58, 14721528.

    Chen, Y., J. Ma, and S. Fomel, 2016, Double sparsity dictionary for seismic noise attenua-tion: Geophysics, 81, no. 2, V17V30.

    Fomel, S., 2002, Applications of plane-wave destruction filters: Geophysics, 67, no. 6, 19461960.

    , 2007, Shaping regularization in geophysical-estimation problems: Geophysics, 72,no. 2, R29R36.

    , 2008, Nonlinear shaping regularization in geophysical inverse problems: 78th AnnualInternational Meeting, SEG, Expanded Abstracts, 20462051.

    Fomel, S., and Y. Liu, 2010, Seislet transform and seislet frame: Geophysics, 75, no. 3,V25V38.

    Fomel, S., P. Sava, I. Vlad, Y. Liu, and V. Bashkardin, 2013, Madagascar: Open-sourcesoftware project for multidimensional data analysis and reproducible computational ex-periments: Journal of Open Research Software, 1, no. 1, e8.

  • Xue et al. 12 FWI with seislet regularization

    Guitton, A., G. Ayeni, and E. Daz, 2012, Constrained full-waveform inversion by modelreparameterization: Geophysics, 77, no. 2, R117R127.

    Krebs, J. R., J. E. Anderson, D. Hinkley, R. Neelamani, S. Lee, A. Baumstein, and M. D.Lacasse, 2009, Fast full-wavefield seismic inversion using encoded sources: Geophysics,74, no. 6, WCC177WCC188.

    Lailly, P., 1983, The seismic inverse problem as a sequence of before stack migrations:Conference on Inverse Scattering, Theory and Application, Society for Industrial andApplied Mathematics, Expanded Abstracts, 206220.

    Li, S., S. Fomel, and H. Zhu, 2014, Frequency-domain reverse-time migration with a sparse-frequency sampling: 84th Annual International Meeting, SEG, Expanded Abstracts,38983904.

    Li, X., A. Y. Aravkin, T. van Leeuwen, and F. J. Herrmann, 2012, Fast randomized full-waveform inversion with compressive sensing: Geophysics, 77, no. 3, A13A17.

    Loris, I., G. Nolet, I. Daubechies, and F. A. Dahlen, 2007, Tomographic inversion usingl1-norm regularization of wavelet coefficients: Geophysical Journal International, 170,no. 1, 359370.

    Ma, Y., D. Hale, B. Gong, and Z. Meng, 2012, Image-guided sparse-model full waveforminversion: Geophysics, 77, no. 4, R189R198.

    Mora, P. R., 1987, Nonlinear two-dimensional elastic inversion of multi-offset seismic data:Geophysics, 52, no. 9, 12111228.

    Morton, S. A., and C. C. Ober, 1998, Faster shot-record depth migration using phaseencoding: 68th Annual International Meeting, SEG, Expanded Abstracts, 11311134.

    Romero, L. A., D. C. Chiglia, C. C. Ober, and S. A. Morton, 2000, Phase encoding of shotrecords in prestack migration: Geophysics, 65, no. 2, 426436.

    Tarantola, A., 1984, Inversion of seismic reflection data in the acoustic approximation:Geophysics, 49, no. 8, 12591266.

    , 1987, Inverse problem theory: Methods for data fitting and model parameter esti-mation: Elsevier Science Publ. Co., Inc.

    Virieux, J., and S. Operto, 2009, An overview of full-waveform inversion in explorationgeophysics: Geophysics, 74, no. 6, WCC1WCC26.

    Xue, Z., Y. Chen, S. Fomel, and J. Sun, 2016, Seismic imaging of incomplete data andsimultaneous-source data using least-squares reverse-time migration with shaping regu-larization: Geophysics, 81, no. 1, S11S20.

    Yin, W., S. Osher, D. Goldfarb, and J. Darbon, 2008, Bregman iterative algorithms forl1-minimization with applications to compressed sensing: SIAM Journal on Imaging Sci-ences, 1, 143168.