def find_faultpos(self,nfaults,mindist,begx=0.05,endx=0.95,begz=0.05,endz=0.95): """ Finds random fault positions between the begx, endx, begz and endz positions Parameters: nfaults: number of fault positions to find mindist: minimum distance between faults begx: minimum x position for placing faults endx: maximum x position for placing faults begz: minimum z position for placing faults endz: maximum z position for placing faults """ pts = []; k = 0 while(len(pts) < nfaults): # Create a coordinate pt = [] pt.append(randfloat(begx,endx)) pt.append(randfloat(begz,endz)) if(k == 0): pts.append(pt) else: keeppoint = True for opt in pts: if(self.distance(pt,opt) < mindist): keeppoint = False break if(keeppoint == True): pts.append(pt) k += 1 return pts
def tinyfaultblock(mb,minpos,maxpos,ofz,space,nfl=10): tfpars = mb.getfaultpos2d(minpos,maxpos,space,space,space,nfaults=nfl) for ifl in progressbar(range(nfl), "ntfaults:"): iftpar = tfpars[ifl] z = ofz + rndut.randfloat(-0.01,0.01) daz = 2000 + rndut.randfloat(-500,500) dz = 1250 + rndut.randfloat(-250,250) theta_shift = 4.0 + rndut.randfloat(-1.0,1.0) mb.fault2d(begx=iftpar[0],begz=z,daz=daz,dz=dz,azim=iftpar[1],theta_die=11,theta_shift=theta_shift,dist_die=2.0,throwsc=10.0,thresh=0.15)
def mediumfaultblock(mb,minpos,maxpos,ofz,space,nfl=10): mfpars = mb.getfaultpos2d(minpos,maxpos,minblk=space,minhor=space,mingrb=space,nfaults=nfl) for ifl in progressbar(range(nfl), "nmfaults:"): ifmpar = mfpars[ifl] z = ofz + rndut.randfloat(-0.01,0.01) daz = 4000 + rndut.randfloat(-1000,1000) dz = 2500 + rndut.randfloat(-1000,1000) theta_shift = 3.0 + rndut.randfloat(-1.0,1.0) mb.fault2d(begx=ifmpar[0],begz=z,daz=daz,dz=dz,azim=ifmpar[1],theta_die=11,theta_shift=theta_shift,dist_die=2.0,throwsc=10.0,thresh=0.2)
def slidingfaultblock(mb,minpos,maxpos,ofz,nfl=6): sfpars = mb.getfaultpos2d(minpos,maxpos,minblk=0.02,minhor=0.2,mingrb=0.2,nfaults=nfl) for ifl in progressbar(range(nfl), "nsfaults:"): ifspar = sfpars[ifl] z = ofz + rndut.randfloat(-0.01,0.01) daz = 7500 + rndut.randfloat(-1000,1000) dz = 15000 + rndut.randfloat(-1000,1000) theta_shift = 3.0 + rndut.randfloat(-1.0,1.0) mb.fault2d(begx=ifspar[0],begz=ofz,daz=daz,dz=dz,azim=ifspar[1],theta_die=11,theta_shift=theta_shift,dist_die=2.0,throwsc=10.0,thresh=0.1)
def getfaultpos2d(self,begx,endx,minblk,minhor,mingrb,nfaults): """ Generates fault positions and azimuths for a large 2D fault block. Ensures that the fault system is geologically realistic Parameters: begx - the leftmost x position of a fault endx - the rightmost x position of a fault minblk - the minimum distance within a fault block (same azimuth) minhor - the minimum distance within a horst block (0 left and 180 right) mingrb - the minimum distance within a graben block (180 left and 0 right) nfaults - the total number of faults Returns a list of x positions and azimuths """ pts = []; k = 0 while(len(pts) < nfaults): # Create an x position and azimuth pt = [] pt.append(randfloat(begx,endx)) pt.append(np.random.choice([0,180])) if(k == 0): pts.append(pt) else: keeppoint = True for opt in pts: # Check their azimuths if(opt[1] == pt[1]): if(np.abs(opt[0]-pt[0]) < minblk): keeppoint = False break else: # Check orientations if(opt[1] == 180 and opt[0] < pt[0]): if(np.abs(opt[0]-pt[0]) < mingrb): keeppoint = False break if(opt[1] == 180 and opt[0] > pt[0]): if(np.abs(opt[0]-pt[0]) < minhor): keeppoint = False break if(opt[1] == 0 and opt[0] < pt[0]): if(np.abs(opt[0]-pt[0]) < minhor): keeppoint = False break if(opt[1] == 0 and opt[0] > pt[0]): if(np.abs(opt[0]-pt[0]) < mingrb): keeppoint = False break if(keeppoint == True): pts.append(pt) k += 1 return pts
def random_hale_vel(nz=900, nx=800, dz=0.005, dx=0.01675, vzin=None): """ Generates a random realization of the Hale/BEI velocity model Parameters: nz - output number of depth samples [900] nx - output number of lateral samples [800] dz - depth sampling [0.005] dx - lateral sampling [0.01675] vzin - a vzin that determines the velocity values [None] """ dzm, dxm = dz * 1000, dx * 1000 nlayer = 200 minvel, maxvel = 1600, 5000 vz = np.linspace(maxvel, minvel, nlayer) if (vzin is not None): vzr = resample(vzin, 90) * 1000 vz[-90:] = vzr[::-1] mb = mdlbuild.mdlbuild(nx, dxm, 20, dy=dxm, dz=dzm, basevel=5000) thicks = np.random.randint(5, 15, nlayer) # Randomize the squishing depth sqz = np.random.choice(list(range(180, 199))) dlyr = 0.05 # Build the sedimentary layers for ilyr in range(nlayer): mb.deposit(velval=vz[ilyr], thick=thicks[ilyr], dev_pos=0.0, layer=50, layer_rand=0.00, dev_layer=dlyr) if (ilyr == sqz): mb.squish(amp=150, azim=90.0, lam=0.4, rinline=0.0, rxline=0.0, mode='perlin', octaves=3, order=3) mb.deposit(1480, thick=40, layer=150, dev_layer=0.0) mb.trim(top=0, bot=nz) # Pos xpos = np.asarray([0.25, 0.30, 0.432, 0.544, 0.6, 0.663]) xhi = xpos + 0.04 xlo = xpos - 0.04 cxpos = np.zeros(xpos.shape) nflt = len(xpos) for iflt in range(nflt): cxpos[iflt] = randfloat(xlo[iflt], xhi[iflt]) if (iflt > 0 and cxpos[iflt] - cxpos[iflt - 1] < 0.07): cxpos[iflt] += 0.07 cdaz = randfloat(16000, 20000) cdz = cdaz + randfloat(0, 6000) # Choose the theta_die theta_die = randfloat(1.5, 3.5) if (theta_die < 2.7): begz = randfloat(0.23, 0.26) else: begz = randfloat(0.26, 0.33) fpr = np.random.choice([True, True, False]) rd = randfloat(52, 65) dec = randfloat(0.94, 0.96) mb.fault2d(begx=cxpos[iflt], begz=begz, daz=cdaz, dz=cdz, azim=180, theta_die=theta_die, theta_shift=4.0, dist_die=2.0, throwsc=35.0, fpr=fpr, rectdecay=rd, dec=dec) velw = mb.vel refw = normalize(mb.get_refl2d()) lblw = mb.get_label2d() return velw * 0.001, refw, lblw
def fault2d(self,begx=0.5,begz=0.5,daz=8000,dz=7000,azim=180, theta_die=12,theta_shift=4.0,dist_die=0.3,throwsc=1.0,thresh=0.1,slcy=None,fpr=False, **kwargs): """ Creates a 2D fault event in the geologic model. Apart from the fact that this method is only 2D, it performs a more accurate interpolation for the fault rotation and also provides an exact procedure for finding the label Parameters: azim - Azimuth of fault [180] begx - Relative location of the beginning of the fault in x [0.5] begy - Relative location of the beginning of the fault in y [0.5] begz - Relative location of the beginning of the fault in z [0.5] dz - Distance away from the center of a circle in z [7000] daz - Distance away in azimuth [8000] dist_die - Controls the die off in the same plane of the fault (e.g., if fault is visible in x, die off is also in x) Large number results in slower dieoff [0.3] theta_die - Controls the die off along the fault (essentially the throw). The larger the number the larger the fault will be. Acts similar to daz. [12] theta_shift - Shift in theta for fault [4.0] throwsc - The total shift in z is divided by this amount (leads to smaller throw) [1.0] thresh - Threshold applied for obtaining the fault labels [50] slcy - y index from where to extract the slice for faulting [ny/2] fpr - Gives the fault a fault plane reflection [False] """ # Check that azim is either 0 or 180 if(azim != 0.0 and azim != 180.0): raise Exception("Azimuth must be 0 or 180 degrees for fault2d") # Extract a slice from the model if it is 3D if(len(self.vel.shape) == 3): if(slcy is None): slcy = int(self.__ny/2) self.vel = self.vel[slcy,:,:] self.lbl = self.lbl[slcy,:,:] self.lyr = self.lyr[slcy,:,:] nz = self.vel.shape[1] # Output velocity model velot = np.zeros(self.vel.shape,dtype='float32') # Output shifts coords = np.zeros([2,*self.vel.shape],dtype='float32') # Output labels lblto = np.zeros(self.vel.shape,dtype='float32') lbltn = np.zeros(self.vel.shape,dtype='float32') self.ec8.fault_shifts2d(nz,self.lbl, azim,begx,begz,dz,daz, theta_shift,dist_die,theta_die,throwsc, lblto,lbltn,coords[0],coords[1]) # Fault velocity model with an accurate interpolation velot = map_coordinates(self.vel,coords,mode='reflect') # Fault label and lyr with nearest neighbor lblto = map_coordinates(self.lbl,coords,order=0) lyrot = map_coordinates(self.lyr,coords,order=0) # Update old label with shifted version self.lbl = lblto # Update layer and velocity models self.vel = velot self.lyr = lyrot # Apply a threshold lbltn = lbltn/np.max(lbltn) lbltm = np.copy(lbltn) idx = lbltn > thresh lbltn[ idx] = 1; lbltn[~idx] = 0 # Create mask for fault plane reflection if(fpr): # Randomly vary decay and strength dec = kwargs.get('dec',randfloat(0.9,0.95)) rectdecay = kwargs.get('rectdecay',randfloat(10,15)) fpmask = self.fpr_mask(lbltm,lbltn,dec=dec,rectdecay=rectdecay) self.vel *= fpmask # Update label self.lbl += lbltn # Apply final threshold to label idx = self.lbl > 1 self.lbl[idx] = 1
def create_randomptbs_loc(nz, nx, nptbs, romin=0.95, romax=1.06, minnaz=150, maxnaz=300, minnax=150, maxnax=300, mindist=200, mincz=None, mincx=None, maxcz=None, maxcx=None, nptsz=1, nptsx=1, octaves=4, period=80, Ngrad=80, persist=0.2, ncpu=1, sigma=20): """ Creates randomly positioned velocity anomalies in a velocity model Parameters nz - number of z samples of velocity model nx - number of x samples of velocity model romins - a list of minimum % magnitudes of velocity perturbation romaxs - a list of maximum % magnitudes of velocity perturbation nazs - list of average sizes of anomalies in z-direction naxs - list of average sizes of anomalies in x-direction mindist - minimum distance between centers of anomalies mincx - minimum x sample to place center of anomaly [0] mincz - minimum z sample to place center of anomaly [0] maxcx - maximum x sample to place center of anomaly [0] maxcz - maximum z sample to place center of anomaly [0] """ # Get ranges if (mincz is None): mincz = 50 if (maxcz is None): maxcz = nz / 2 if (mincx is None): mincx = 20 if (maxcx is None): maxcx = nz - 20 # Find centers ctrs = [] k = 0 while (len(ctrs) < nptbs): ctr = [] ctr.append(np.random.randint(mincz, maxcz)) ctr.append(np.random.randint(mincx, maxcx)) if (k == 0): ctr.append(ctr) else: keeppoint = True for ict in ctrs: if (distance(ctr, ict) < mindist): keeppoint = False break if (keeppoint == True): ctrs.append(ctr) k += 1 # Create each perturbation velout = np.ones([nz, nx], dtype='float32') for iptb in range(nptbs): # Create naz and nax from the min and the max nax = np.random.randint(minnax, maxnax) naz = np.random.randint(minnaz, maxnaz) # Create romin and romax from the min and max if (romin < 1.0 and romax > 1.0 and nptbs > 1): if (np.random.choice([0, 1])): iromin = romin + randfloat(0.001, 0.01) iromax = 1.0 + randfloat(0.001, 0.01) else: iromax = romax + randfloat(0.001, 0.01) iromin = 1.0 - randfloat(0.001, 0.01) else: iromin = romin iromax = romax ptb = create_randomptb_loc(nz, nx, iromin, iromax, naz, nax, ctrs[iptb][0], ctrs[iptb][1], nptsz=nptsz, nptsx=nptsx, octaves=octaves, period=period, Ngrad=Ngrad, persist=persist, ncpu=1, sigma=sigma) velout *= ptb return velout
def undulatingrandfaults2d(nz=512,nx=1000,dz=12.5,dx=25.0,nlayer=21,minvel=1600,maxvel=3000,rect=0.5, nfx=3,ofx=0.4,dfx=0.1,ofz=0.3,noctaves=None,npts=None,amp=None): """ Builds a 2D faulted velocity model with undulating layers Returns the velocity model, reflectivity, fault labels and a zero-offset image Parameters: nz - number of depth samples [512] nx - number of lateral samples[1000] dz - depth sampling interval [12.5] dx - lateral sampling interval [12.5] nlayer - number of deposited layers (there exist many fine layers within a deposit) [21] nfx - number of faults [0.3] ofx - Starting position of faults (percentage of total model) [0.4] dx - Spacing between faults (percentage of total model) [0.1] ofz - Central depth of faults (percentage of total model) [0.3] rect - radius for gaussian smoother [0.5] noctaves - octaves perlin parameters for squish [varies between 3 and 6] amp - amplitude of folding [varies between 200 and 500] npts - grid size for perlin noise [3] Returns: The velocity, reflectivity, fault label and image all of size [nx,nz] """ # Model building object # Remember to change dist_die based on ny mb = mdlbuild.mdlbuild(nx,dx,ny=20,dy=dx,dz=dz,basevel=5000) nzi = 1000 # internal size is 1000 # Propagation velocities props = np.linspace(maxvel,minvel,nlayer) # Specify the thicknesses thicks = np.random.randint(40,61,nlayer) dlyr = 0.05 for ilyr in progressbar(range(nlayer), "ndeposit:", 40): mb.deposit(velval=props[ilyr],thick=thicks[ilyr],dev_pos=0.0,layer=50,layer_rand=0.00,dev_layer=dlyr) if(ilyr == int(nlayer-2)): amp = rndut.randfloat(200,500) octs = np.random.randint(2,7) npts = np.random.randint(2,5) mb.squish(amp=amp,azim=90.0,lam=0.4,rinline=0.0,rxline=0.0,mode='perlin',npts=npts,octaves=octs,order=3) # Water deposit mb.deposit(1480,thick=80,layer=150,dev_layer=0.0) # Smooth the interface mb.smooth_model(rect1=1,rect2=5,rect3=1) # Trim model before faulting mb.trim(0,1100) #XXX: Thresh should be a function of theta_shift # Generate the fault positions flttype = np.random.choice([0,1,2,3,4,5]) if(flttype == 0): largefaultblock(mb,0.3,0.7,ofz,nfl=6) elif(flttype == 1): slidingfaultblock(mb,0.3,0.7,ofz,nfl=6) elif(flttype == 2): mediumfaultblock(mb,0.3,0.7,0.25,space=0.02,nfl=10) elif(flttype == 3): mediumfaultblock(mb,0.3,0.7,0.25,space=0.005,nfl=20) elif(flttype == 4): tinyfaultblock(mb,0.3,0.7,0.25,space=0.02,nfl=10) else: tinyfaultblock(mb,0.3,0.7,0.25,space=0.005,nfl=20) # Get the model vel = gaussian_filter(mb.vel[:,:nzi].T,sigma=rect).astype('float32') lbl = mb.get_label2d()[:,:nzi].T ref = mb.get_refl2d()[:,:nzi].T # Parameters for ricker wavelet nt = 250; ot = 0.0; dt = 0.001; ns = int(nt/2) amp = 1.0; dly = 0.125 minf = 100.0; maxf = 120.0 # Create normalized image f = rndut.randfloat(minf,maxf) wav = ricker(nt,dt,f,amp,dly) img = dlut.normalize(np.array([np.convolve(ref[:,ix],wav) for ix in range(nx)])[:,ns:nzi+ns].T) nze = dlut.normalize(bandpass(np.random.rand(nzi,nx)*2-1, 2.0, 0.01, 2, pxd=43))/rndut.randfloat(3,5) img += nze # Window the models and return f1 = 50 velwind = vel[f1:f1+nz,:] lblwind = lbl[f1:f1+nz,:] refwind = ref[f1:f1+nz,:] imgwind = img[f1:f1+nz,:] return velwind,refwind,imgwind,lblwind
def velfaultsrandom(nz=512,nx=1024,ny=20,dz=12.5,dx=25.0,nlayer=20, minvel=1600,maxvel=5000,rect=0.5, verb=True,**kwargs): """ Builds a 2D highly faulted and folded velocity model. Returns the velocity model, reflectivity, fault labels and a zero-offset image Parameters: nz - number of depth samples [512] nx - number of lateral samples [1024] dz - depth sampling interval [25.0] dx - lateral sampling interval [25.0] nlayer - number of deposited layers (there exist many fine layers within a deposit) [20] minvel - minimum velocity in model [1600] maxvel - maximum velocity in model [5000] rect - length of gaussian smoothing [0.5] verb - verbosity flag [True] Returns The velocity, reflectivity, fault label and image all of size [nx,nz] """ # Internal model size nzi = 1000; nxi = 1000 # Model building object mb = mdlbuild.mdlbuild(nxi,dx,ny,dy=dx,dz=dz,basevel=5000) # First build the v(z) model props = mb.vofz(nlayer,minvel,maxvel,npts=kwargs.get('nptsvz',2)) # Specify the thicknesses thicks = np.random.randint(40,61,nlayer) # Determine when to fold the deposits sqlyrs = sorted(mb.findsqlyrs(3,nlayer,5)) csq = 0 dlyr = 0.05 for ilyr in progressbar(range(nlayer), "ndeposit:", 40, verb=verb): mb.deposit(velval=props[ilyr],thick=thicks[ilyr],dev_pos=0.0, layer=kwargs.get('layer',150),layer_rand=0.00,dev_layer=dlyr) # Random folding if(ilyr in sqlyrs): if(sqlyrs[csq] < 15): # Random amplitude variation in the folding amp = np.random.rand()*(3000-500) + 500 mb.squish(amp=amp,azim=90.0,lam=0.4,rinline=0.0,rxline=0.0,mode='perlin',order=3) elif(sqlyrs[csq] >= 15 and sqlyrs[csq] < 18): amp = np.random.rand()*(1800-500) + 500 mb.squish(amp=amp,azim=90.0,lam=0.4,rinline=0.0,rxline=0.0,mode='perlin',order=3) else: amp = np.random.rand()*(500-300) + 300 mb.squish(amp=amp,azim=90.0,lam=0.4,rinline=0.0,rxline=0.0,mode='perlin') csq += 1 # Water deposit mb.deposit(1480,thick=50,layer=150,dev_layer=0.0) # Smooth any unconformities mb.smooth_model(rect1=1,rect2=5,rect3=1) # Trim model before faulting mb.trim(0,1100) # Fault it up! azims = [0.0,180.0] fprs = [True,False] # Large faults nlf = np.random.randint(2,5) for ifl in progressbar(range(nlf), "nlfaults:", 40, verb=verb): azim = np.random.choice(azims) fpr = np.random.choice(fprs) xpos = rndut.randfloat(0.1,0.9) mb.largefault(azim=azim,begz=0.65,begx=xpos,begy=0.5,dist_die=4.0,tscale=6.0,fpr=fpr,twod=True) # Medium faults nmf = np.random.randint(3,6) for ifl in progressbar(range(nmf), "nmfaults:", 40, verb=verb): azim = np.random.choice(azims) fpr = np.random.choice(fprs) xpos = rndut.randfloat(0.05,0.95) mb.mediumfault(azim=azim,begz=0.65,begx=xpos,begy=0.5,dist_die=4.0,tscale=3.0,fpr=fpr,twod=True) # Small faults (sliding or small) nsf = np.random.randint(5,10) for ifl in progressbar(range(nsf), "nsfaults:", 40, verb=verb): azim = np.random.choice(azims) fpr = np.random.choice(fprs) xpos = rndut.randfloat(0.05,0.95) zpos = rndut.randfloat(0.2,0.5) mb.smallfault(azim=azim,begz=zpos,begx=xpos,begy=0.5,dist_die=4.0,tscale=2.0,fpr=fpr,twod=True) # Tiny faults ntf = np.random.randint(5,10) for ifl in progressbar(range(ntf), "ntfaults:", 40, verb=verb): azim = np.random.choice(azims) xpos = rndut.randfloat(0.05,0.95) zpos = rndut.randfloat(0.15,0.3) mb.tinyfault(azim=azim,begz=zpos,begx=xpos,begy=0.5,dist_die=4.0,tscale=2.0,twod=True) # Parameters for ricker wavelet nt = kwargs.get('nt',250); ot = 0.0; dt = kwargs.get('dt',0.001); ns = int(nt/2) amp = 1.0; dly = kwargs.get('dly',0.125) minf = kwargs.get('minf',60.0); maxf = kwargs.get('maxf',100.0) f = kwargs.get('f',None) # Get model vel = gaussian_filter(mb.vel[:,:nzi],sigma=rect).astype('float32') lbl = mb.get_label2d()[:,:nzi] # Resample to output size velr = dlut.resample(vel,[nx,nz],kind='quintic') lblr = dlut.thresh(dlut.resample(lbl,[nx,nz],kind='linear'),0) refr = mb.calcrefl2d(velr) # Create normalized image if(f is None): f = rndut.randfloat(minf,maxf) wav = ricker(nt,dt,f,amp,dly) img = dlut.normalize(np.array([np.convolve(refr[ix,:],wav) for ix in range(nx)])[:,ns:nz+ns]) # Create noise nze = dlut.normalize(bandpass(np.random.rand(nx,nz)*2-1, 2.0, 0.01, 2, pxd=43))/rndut.randfloat(3,5) img += nze if(kwargs.get('transp',False) == True): velt = np.ascontiguousarray(velr.T).astype('float32') reft = np.ascontiguousarray(refr.T).astype('float32') imgt = np.ascontiguousarray(img.T).astype('float32') lblt = np.ascontiguousarray(lblr.T).astype('float32') else: velt = np.ascontiguousarray(velr).astype('float32') reft = np.ascontiguousarray(refr).astype('float32') imgt = np.ascontiguousarray(img).astype('float32') lblt = np.ascontiguousarray(lblr).astype('float32') if(kwargs.get('km',True)): velt /= 1000.0 return velt,reft,imgt,lblt
def layeredfaults2d(nz=512,nx=1000,dz=12.5,dx=25.0,nlayer=21,minvel=1600,maxvel=3000,rect=0.5, nfx=3,ofx=0.4,dfx=0.1,ofz=0.3): """ Builds a 2D layered, v(z) fault model. Returns the velocity model, reflectivity, fault labels and a zero-offset image Parameters: nz - number of depth samples [512] nx - number of lateral samples[1000] dz - depth sampling interval [12.5] dx - lateral sampling interval [12.5] nlayer - number of deposited layers (there exist many fine layers within a deposit) [21] nfx - number of faults [0.3] ofx - Starting position of faults (percentage of total model) [0.4] dx - Spacing between faults (percentage of total model) [0.1] ofz - Central depth of faults (percentage of total model) [0.3] rect - radius for gaussian smoother [0.5] Returns: The velocity, reflectivity, fault label and image all of size [nx,nz] """ # Model building object mb = mdlbuild.mdlbuild(nx,dx,ny=200,dy=dx,dz=dz,basevel=5000) nzi = 1000 # internal size is 1000 # Propagation velocities props = np.linspace(maxvel,minvel,nlayer) # Specify the thicknesses thicks = np.random.randint(40,61,nlayer) dlyr = 0.05 for ilyr in progressbar(range(nlayer), "ndeposit:", 40): mb.deposit(velval=props[ilyr],thick=thicks[ilyr],dev_pos=0.0,layer=50,layer_rand=0.00,dev_layer=dlyr) # Water deposit mb.deposit(1480,thick=80,layer=150,dev_layer=0.0) # Trim model before faulting mb.trim(0,1100) # Put in the faults for ifl in progressbar(range(nfx), "nfaults:"): x = ofx + ifl*dfx mb.fault2d(begx=x,begz=ofz,daz=8000,dz=5000,azim=0.0,theta_die=11,theta_shift=4.0,dist_die=0.3,throwsc=10.0) # Get the model vel = gaussian_filter(mb.vel[:,:nzi].T,sigma=rect).astype('float32') lbl = mb.get_label2d()[:,:nzi].T ref = mb.get_refl2d()[:,:nzi].T # Parameters for ricker wavelet nt = 250; ot = 0.0; dt = 0.001; ns = int(nt/2) amp = 1.0; dly = 0.125 minf = 100.0; maxf = 120.0 # Create normalized image f = rndut.randfloat(minf,maxf) wav = ricker(nt,dt,f,amp,dly) img = dlut.normalize(np.array([np.convolve(ref[:,ix],wav) for ix in range(nx)])[:,ns:nzi+ns].T) nze = dlut.normalize(bandpass(np.random.rand(nzi,nx)*2-1, 2.0, 0.01, 2, pxd=43))/rndut.randfloat(3,5) img += nze # Window the models and return f1 = 50 velwind = vel[f1:f1+nz,:] lblwind = lbl[f1:f1+nz,:] refwind = ref[f1:f1+nz,:] imgwind = img[f1:f1+nz,:] return velwind,refwind,imgwind,lblwind