Example #1
0
  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
Example #2
0
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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
  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
Example #6
0
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
Example #7
0
  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
Example #8
0
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
Example #9
0
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
Example #10
0
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
Example #11
0
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