Exemplo n.º 1
0
def load_labeled_flat_data(trfile, vafile, begex=None, endex=None):
    """ Loads flattened labeled data into numpy arrays """
    # Get training number of examples
    hftr = h5py.File(trfile, 'r')
    trkeys = list(hftr.keys())
    ntr = int(len(trkeys) / 2)
    # Get the validation number of examples
    if (vafile is not None):
        hfva = h5py.File(vafile, 'r')
        vakeys = list(hfva.keys())
        nva = int(len(vakeys) / 2)
    else:
        nva = 0
        vakeys = []
    # Get shape of examples
    xshape = hftr[trkeys[0]].shape
    yshape = hftr[trkeys[0 + ntr]].shape
    ndim = len(xshape)
    # Get number of examples
    if (begex is None or endex is None):
        begex = 0
        endex = ntr
        nex = ntr
    else:
        nex = endex - begex
    if (ndim == 3):
        allx = np.zeros([(nex + nva), xshape[0], xshape[1], xshape[2]],
                        dtype='float32')
    elif (ndim == 4):
        allx = np.zeros(
            [(nex + nva), xshape[0], xshape[1], xshape[2], xshape[3]],
            dtype='float32')
    ally = np.zeros([(nex + nva), yshape[0]], dtype='float32')
    # Get all training examples
    for itr in progressbar(range(begex, endex), "numtr:"):
        if (ndim == 3):
            allx[itr, :, :, :] = hftr[trkeys[itr]][:]
        elif (ndim == 4):
            allx[itr, :, :, :, :] = hftr[trkeys[itr]][:]
        ally[itr, :] = hftr[trkeys[itr + ntr]][:]
    # Get all validation examples
    for iva in progressbar(range(nva), "numva:"):
        if (ndim == 3):
            allx[iva, :, :, :] = hfva[vakeys[iva]][:]
        elif (ndim == 4):
            allx[iva, :, :, :, :] = hfva[vakeys[iva]][:]
        ally[iva, :] = hfva[vakeys[iva + nva]][:]
    # Close the files
    hftr.close()
    if (vafile != None): hfva.close()

    return allx, ally
Exemplo n.º 2
0
  def largehorstgraben_block(self,azim=0.0,begz=0.1,xdir=True,rand=True):
    """
    Puts in a small horst-graben block fault system.
    Attempts to span most of the lateral range of the model.
    For now, will only give nice faults along 0,90,180,270 azimuths

    Parameters:
      azim - azimuth along which faults are oriented [0.0]
      begz - beginning position in z for fault (same for all) [0.5]
      xdir - Whether the faults should be spaced along the x direction [True]
      rand - small random variations in the throw of the faults [True]
    """
    dx   = 0.0; dy   = 0.0
    begx = 0.5; begy = 0.5
    if(xdir):
      dx = 0.32; begx = 0.05
    else:
      dy = 0.32; begy = 0.05
    for ifl in progressbar(range(3), "ngrabens:", 40):
      daz = 15000; dz = 5000
      if(rand):
        daz += np.random.rand()*(2000) - 1000
        dz  += np.random.rand()*(2000) - 1000
      # Put in graben pair along x or y
      if(xdir):
        self.fault(begx=begx     ,begy=begy,begz=begz,daz=daz,dz=dz,azim=azim+180.0,theta_die=12.0,theta_shift=4.0,dist_die=1.5,perp_die=1.0,thresh=200)
        self.fault(begx=begx+0.16,begy=begy,begz=begz,daz=daz,dz=dz,azim=azim      ,theta_die=12.0,theta_shift=4.0,dist_die=1.5,perp_die=1.0,thresh=200)
      else:
        self.fault(begx=begx,begy=begy     ,begz=begz,daz=daz,dz=dz,azim=azim+180.0,theta_die=12.0,theta_shift=4.0,dist_die=1.5,perp_die=1.0,thresh=200)
        self.fault(begx=begx,begy=begy+0.16,begz=begz,daz=daz,dz=dz,azim=azim      ,theta_die=12.0,theta_shift=4.0,dist_die=1.5,perp_die=1.0,thresh=200)
      # Move along x or y
      begx += dx; begy += dy
Exemplo n.º 3
0
  def sliding_block(self,nfault=5,azim=0.0,begz=0.5,begx=0.5,begy=0.5,dx=0.2,dy=0.0,rand=True):
    """
    Puts in sliding fault block system. For now, only will give nice faults along
    0,90,180,270 azimuths

    Parameters:
      nfault - number of faults in the system [5]
      azim   - azimuth along which faults are oriented [0.0]
      begz   - beginning position in z for fault (same for all) [0.6]
      begx   - beginning position in x for system [0.5]
      begy   - beginning position in y for system [0.5]
      dx     - spacing between faults in the x direction [0.2]
      dy     - spacing between faults in the y direction [0.0]
      rand   - small random variations in the positioning and throw of the faults [True]
    """
    signx = 1; signy = 1
    if(begx > 0.5):
      signx = -1
    if(begy > 0.5):
      signy = -1
    for ifl in progressbar(range(nfault), "ndfaults:", 40):
      daz = 10000; dz = 25000; dxi = dx; dyi = dy
      if(rand):
        daz += np.random.rand()*(2000) - 1000
        dz  += np.random.rand()*(2000) - 1000
        dxi += np.random.rand()*(dxi) - dxi/2
        dyi += np.random.rand()*(dyi) - dyi/2
      self.fault(begx=begx,begy=begy,begz=begz,daz=daz,dz=dz,azim=azim,theta_die=12.0,theta_shift=4.0,dist_die=1.5,perp_die=1.0,thresh=200)
      # Move along x or y
      begx += signx*dxi; begy += signy*dyi
Exemplo n.º 4
0
def splith5(fin, f1, f2, split=0.8, rand=False, clean=True):
    """
  Splits an H5 file into two other files.
  Useful for splitting data into training and validation
  """
    hfin = h5py.File(fin, 'r')
    hf1 = h5py.File(f1, 'w')
    hf2 = h5py.File(f2, 'w')
    keys = list(hfin.keys())
    nb = int(len(keys) / 2)
    nf1 = int(split * nb)
    nf2 = nb - nf1
    if (rand):
        choices = list(range(nb))
        idxs = random.sample(choices, nf1)
    else:
        idxs = list(range(nf1))
    for idx in progressbar(range(nb), "nbatches:"):
        if idx in idxs:
            hfin.copy(keys[idx], hf1)
            hfin.copy(keys[idx + nb], hf1)
        else:
            hfin.copy(keys[idx], hf2)
            hfin.copy(keys[idx + nb], hf2)
    hfin.close()
    hf1.close()
    hf2.close()
    # Remove the original file
    if (clean):
        sp = subprocess.check_call('rm %s' % (fin), shell=True)
Exemplo n.º 5
0
def makemovie_mpl(arr,odir,ftype='png',qc=False,skip=1,pttag=False,**kwargs):
  """
  Saves each frame on the fast axis to a png for viewing

  Parameters:
    arr       - input array where the frames are on the fast axis
    odir      - the output directory where to save the frames
    ftype     - the type (extension) of figure to save [png]
    qc        - look at each frame as it is saved [False]
    skip      - whether to skip frames [1]
    pttag     - write the frame number in pretty (unix-friendly) format
    wbox      - the first dimension of the figure size (figure width) [10]
    hbox      - the second dimension of the figure size (figure height) [10]
    xmin      - the minimum lateral point in your data [0.0]
    xmax      - the maximum lateral point in your data (typically (nx-1)*dx) [nx]
    zmin      - the minimum depth point in your data [0.0]
    zmax      - the maximum depth point in your data (typically (nz-1)*dz) [nz]
    vmin      - the minumum value desired to be plotted (min(data))
    vmax      - the maximum value desired to be plotted (max(data))
    pclip     - a scale to be applied to shrink or expand the dynamic range
    xlabel    - the label of the x-axis [None]
    ylabel    - the label of the y-axis [None]
    labelsize - the fontsize of the labels [18]
    ticksize  - the fontsize of the ticks [18]
    ttlstring - title to be printed. Can be printed of the form ttlstring%(ottl + dttl*(framenumber))
    ottl      - the first title value to be printed
    dttl      - the sampling of the title value to be printed
    aratio    - aspect ratio of the figure [1.0]
  """
  # Check if directory exists
  if(os.path.isdir(odir) == False):
    os.mkdir(odir)
  nfr = arr.shape[2]
  k = 0
  frames = np.arange(0,nfr,skip)
  vmin = np.min(arr); vmax = np.max(arr)
  for ifr in progressbar(frames, "frames"):
    fig = plt.figure(figsize=(kwargs.get("wbox",10),kwargs.get("hbox",10)))
    ax = fig.add_subplot(111)
    ax.imshow(arr[:,:,ifr],cmap=kwargs.get("cmap","gray"),
        extent=[kwargs.get("xmin",0),kwargs.get("xmax",arr.shape[1]),
          kwargs.get("zmax",arr.shape[0]),kwargs.get("zmin",0)],
        vmin=kwargs.get("vmin",vmin)*kwargs.get('pclip',1.0),
        vmax=kwargs.get("vmax",vmax)*kwargs.get('pclip',1.0))
    ax.set_xlabel(kwargs.get('xlabel',''),fontsize=kwargs.get('labelsize',18))
    ax.set_ylabel(kwargs.get('ylabel',''),fontsize=kwargs.get('labelsize',18))
    ax.tick_params(labelsize=kwargs.get('ticksize',18))
    if('%' in kwargs.get('ttlstring'),''):
      ax.set_title(kwargs.get('ttlstring','')%(kwargs.get('ottl',0.0) + kwargs.get('dttl',1.0)*k),
          fontsize=kwargs.get('labelsize',18))
    ax.set_aspect(kwargs.get('aratio',1.0))
    if(pttag):
      tag = create_inttag(k,nfr)
    else:
      tag = str(k)
    plt.savefig(odir+'/'+tag+'.'+ftype,bbox_inches='tight',dpi=kwargs.get("dpi",150))
    k += 1
    if(qc):
      plt.show()
Exemplo n.º 6
0
def load_alldata(trfile, vafile, dsize, begex=None, endex=None, verb=False):
    """ Loads all data and labels into numpy arrays """
    # Get training number of examples
    hftr = h5py.File(trfile, 'r')
    trkeys = list(hftr.keys())
    ntr = int(len(trkeys) / 2)
    # Get the validation number of examples
    if (vafile != None):
        hfva = h5py.File(vafile, 'r')
        vakeys = list(hfva.keys())
        nva = int(len(vakeys) / 2)
    else:
        nva = 0
        vakeys = []
    # Get shape of examples
    xshape = hftr[trkeys[0]].shape
    yshape = hftr[trkeys[0 + ntr]].shape
    # Get number of examples
    if (begex is None or endex is None):
        begex = 0
        endex = ntr
        nex = ntr
    else:
        nex = endex - begex
    # Allocate output arrays
    allx = np.zeros([(nex + nva) * dsize, *xshape[1:]], dtype='float32')
    ally = np.zeros([(nex + nva) * dsize, *yshape[1:]], dtype='float32')
    k = 0
    # Get all training examples
    for itr in progressbar(range(begex, endex), "numtr:", verb=verb):
        for iex in range(dsize):
            allx[k] = hftr[trkeys[itr]][iex]
            ally[k] = hftr[trkeys[itr + ntr]][iex]
            k += 1
    # Get all validation examples
    for iva in progressbar(range(nva), "numva:"):
        for iex in range(dsize):
            allx[k] = hfva[vakeys[iva]][iex]
            ally[k] = hfva[vakeys[iva + nva]][iex]
            k += 1
    # Close the files
    hftr.close()
    if (vafile != None): hfva.close()

    return allx, ally
Exemplo n.º 7
0
def load_allpatchdata(trfile, vafile, dsize):
    """
  Loads all data and labels into numpy arrays

  Works both for the SSIM residual migration training
  and the patchwise fault classification training
  """
    # Get training number of examples
    hftr = h5py.File(trfile, 'r')
    trkeys = list(hftr.keys())
    ntr = int(len(trkeys) / 2)
    # Get the validation number of examples
    if (vafile != None):
        hfva = h5py.File(vafile, 'r')
        vakeys = list(hfva.keys())
        nva = int(len(vakeys) / 2)
    else:
        nva = 0
        vakeys = []
    # Get shape of examples
    xshape = hftr[trkeys[0]].shape
    yshape = hftr[trkeys[0 + ntr]].shape
    # Allocate output arrays
    if (len(xshape) == 4):
        allx = np.zeros([(ntr + nva) * dsize, xshape[1], xshape[2], xshape[3]],
                        dtype='float32')
    ally = np.zeros([(ntr + nva) * dsize, yshape[1]], dtype='float32')
    k = 0
    # Get all training examples
    for itr in progressbar(range(ntr), "numtr:"):
        for iex in range(dsize):
            allx[k, :, :, :] = hftr[trkeys[itr]][iex, :, :, :]
            ally[k, :] = hftr[trkeys[itr + ntr]][iex, :]
            k += 1
    # Get all validation examples
    for iva in progressbar(range(nva), "numva:"):
        for iex in range(dsize):
            allx[k, :, :, :] = hfva[vakeys[iva]][iex, :, :, :]
            ally[k, :] = hfva[vakeys[iva + nva]][iex, :]
            k += 1
    # Close the files
    hftr.close()
    if (vafile != None): hfva.close()

    return allx, ally
Exemplo n.º 8
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)
Exemplo n.º 9
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)
Exemplo n.º 10
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)
Exemplo n.º 11
0
def resample(img,new_shape,kind='linear',ds=[]):
  """
  Resamples an image. Can work up to 4D numpy arrays.
  assumes that the nz and nx axes are the last two (fastest)
  """
  if(len(img.shape) >= 2):
   # Original coordinates
    length=img.shape[-1]
    height=img.shape[-2]
    x=np.linspace(0,length,length)
    y=np.linspace(0,height,height)
    # New coordinates for interpolation
    xnew=np.linspace(0,length,new_shape[1])
    ynew=np.linspace(0,height,new_shape[0])
  elif(len(img.shape) == 1):
    length = img.shape[0]
    x = np.linspace(0,length,length)
    # New coordinates for interpolation
    xnew = np.linspace(0,length,new_shape)
  # Compute new samplings
  if(len(ds) != 0):
      dout = []
      lr = new_shape[1]/length
      hr = new_shape[0]/height
      dout.append(ds[1]/lr)
      dout.append(ds[0]/hr)
  # Perform the interpolation
  if len(img.shape)==4:
    res = np.zeros([img.shape[0],img.shape[1],new_shape[0],new_shape[1]],dtype='float32')
    for i in range(img.shape[0]):
      for j in range(img.shape[1]):
        f = interpolate.interp2d(x,y,img[i,j,:,:],kind=kind)
        res[i,j,:,:] = f(xnew,ynew)
  elif len(img.shape)==3:
    res = np.zeros([img.shape[0],new_shape[0],new_shape[1]],dtype='float32')
    for i in progressbar(range(img.shape[0]),"nimg:"):
      f = interpolate.interp2d(x,y,img[i,:,:],kind=kind)
      res[i,:,:] = f(xnew,ynew)
  elif len(img.shape)==2:
    res = np.zeros([new_shape[0],new_shape[1]],dtype='float32')
    f=interpolate.interp2d(x,y,img,kind=kind)
    res[:] = f(xnew,ynew)
  elif len(img.shape)==1:
    res = np.zeros(new_shape,dtype='float32')
    f = interpolate.interp1d(x,img,kind=kind)
    res[:] = f(xnew)

  if(len(ds) == 0):
    return res
  else:
    return res,dout
Exemplo n.º 12
0
def load_unlabeled_flat_data(filein, begex=None, endex=None):
    """ Loads in flattened unlabeled data """
    hftr = h5py.File(filein, 'r')
    trkeys = list(hftr.keys())
    ntr = int(len(trkeys))
    xshape = hftr[trkeys[0]].shape
    if (begex is None or endex is None):
        begex = 0
        endex = ntr
        allx = np.zeros([ntr, xshape[0], xshape[1], xshape[2]],
                        dtype='float32')
    else:
        nex = endex - begex
        allx = np.zeros([nex, xshape[0], xshape[1], xshape[2]],
                        dtype='float32')
    for itr in progressbar(range(begex, endex), "numex:"):
        allx[itr, :, :, :] = hftr[trkeys[itr]][:]
    # Close H5 file
    hftr.close()

    return allx
Exemplo n.º 13
0
def load_all_unlabeled_data(filein, begex=None, endex=None):
    """ Loads all data into a numpy array """
    # Get training number of examples
    hftr = h5py.File(filein, 'r')
    trkeys = list(hftr.keys())
    ntr = int(len(trkeys))
    # Get shape of examples
    xshape = hftr[trkeys[0]].shape
    # Allocate output arrays
    allx = []
    k = 0
    # Get all training examples
    if (begex is None or endex is None):
        begex = 0
        endex = ntr
    for itr in progressbar(range(begex, endex), "numtr:"):
        dsize = hftr[trkeys[itr]].shape[0]
        for iex in range(dsize):
            allx.append(hftr[trkeys[itr]][iex])
            k += 1
    # Close the file
    hftr.close()
    return np.asarray(allx)
Exemplo n.º 14
0
def load_allflddata(fldfile, dsize):
    """ Loads all field (unlabeled) data into a numpy array """
    # Get training number of examples
    hffld = h5py.File(fldfile, 'r')
    fldkeys = list(hffld.keys())
    nfld = int(len(fldkeys) / 2)
    # Get shape of examples
    xshape = hffld[fldkeys[0]].shape
    # Allocate output arrays
    if (len(xshape) == 4):
        allx = np.zeros([(nfld) * dsize, xshape[1], xshape[2], xshape[3]],
                        dtype='float32')
    elif (len(xshape) == 3):
        allx = np.zeros([(nfld) * dsize, xshape[1], xshape[2]],
                        dtype='float32')
    k = 0
    # Get all field examples
    for ifld in progressbar(range(nfld), "numfld:"):
        for iex in range(dsize):
            allx[k, :, :, :] = hffld[fldkeys[ifld]][iex, :, :, :]
            k += 1

    return allx
Exemplo n.º 15
0
def clean_examples(ifiles, skips, sep, verb=False) -> None:
    """
  Cleans examples from a .H file

  Parameters:
    ifiles - input list of .H files (assumes all files same shape)
    skips  - file indices over which to skip for cleaning
    verb   - verbosity flag [False]
  """
    if (type(ifiles) is not list):
        raise Exception("Input files must be within a list")
    nf = len(ifiles)

    # Prepare the output files
    ofiles = []
    for ifile in ifiles:
        bname = opsys.path.splitext(ifile)[0]
        ofiles.append(bname + '-cln.H')

    # Get the total enumber of examples
    taxes = sep.read_header(ifiles[0])
    nex = taxes.n[-1]
    os = taxes.o[:-1]
    ds = taxes.d[:-1]

    for iex in progressbar(range(nex), "nex:", verb=verb):
        if (iex not in skips):
            for ifile in range(nf):
                axes, dat = sep.read_wind(ifiles[ifile], fw=iex, nw=1)
                dat = dat.reshape(axes.n, order='F')
                if (iex == 0):
                    sep.write_file(ofiles[ifile], dat, os=os, ds=ds)
                elif (iex == 1):
                    sep.append_file(ofiles[ifile], dat, newaxis=True)
                else:
                    sep.append_file(ofiles[ifile], dat)
Exemplo n.º 16
0
    def model_data(self,
                   wav,
                   t0,
                   owc,
                   dwc,
                   vel,
                   ref,
                   nrmax=3,
                   eps=0.,
                   dtmax=5e-05,
                   ntx=0,
                   nty=0,
                   px=0,
                   py=0,
                   nthrds=1,
                   sverb=True,
                   wverb=True):
        """
    3D modeling of single scattered (Born) data with the one-way
    wave equation (single square root (SSR), split-step Fourier method).

    Parameters:
      wav    - the input wavelet (source time function) [nt]
      t0     - time zero of input wavelet
      owc    - minimum frequency of wavelet
      dwc    - frequency sampling of wavelet
      vel    - input velocity model [nz,ny,nx]
      ref    - input reflectivity model [nz,ny,nx]
      nrmax  - maximum number of reference velocities [3]
      eps    - stability parameter [0.]
      dtmax  - maximum time error [5e-05]
      ntx    - size of taper in x direction (samples) [0]
      nty    - size of taper in y direction (samples) [0]
      px     - amount of padding in x direction (samples)
      py     - amount of padding in y direction (samples)
      nthrds - number of OpenMP threads to use for frequency parallelization [1]
      sverb  - verbosity flag for shot progress bar [True]
      wverb  - verbosity flag for frequency progress bar [False]

    Returns:
      the data at the surface [nw,nry,nrx]
    """
        # Get dimensions
        nwc = wav.shape[0]

        # Single square root object
        ssf = ssr3(
            self.__nx,
            self.__ny,
            self.__nz,  # Spatial Sizes
            self.__dx,
            self.__dy,
            self.__dz,  # Spatial Samplings
            nwc,
            owc,
            dwc,
            eps,  # Frequency axis
            ntx,
            nty,
            px,
            py,  # Taper and padding
            dtmax,
            nrmax,
            nthrds)  # Reference velocities and threads

        # Compute slowness and reference slownesses
        slo = 1 / vel
        ssf.set_slows(slo)

        # Allocate output data (surface wavefield) and receiver data
        datw = np.zeros([nwc, self.__ny, self.__nx], dtype='complex64')
        recw = np.zeros([self.__ntr, nwc], dtype='complex64')

        # Allocate the source for one shot
        sou = np.zeros([nwc, self.__ny, self.__nx], dtype='complex64')

        # Loop over sources
        ntr = 0
        for iexp in progressbar(range(self.__nexp), "nexp:", verb=sverb):
            # Get the source coordinates
            sy = self.__srcy[iexp]
            sx = self.__srcx[iexp]
            isy = int((sy - self.__oy) / self.__dy + 0.5)
            isx = int((sx - self.__ox) / self.__dx + 0.5)
            # Create the source for this shot
            sou[:] = 0.0
            sou[:, isy, isx] = wav[:]
            # Downward continuation
            datw[:] = 0.0
            ssf.modallw(ref, sou, datw, wverb)
            # Restrict to receiver locations
            datwt = np.ascontiguousarray(np.transpose(
                datw, (1, 2, 0)))  # [nwc,ny,nx] -> [ny,nx,nwc]
            ssf.restrict_data(self.__nrec[iexp], self.__recy[ntr:],
                              self.__recx[ntr:], self.__oy, self.__ox, datwt,
                              recw[ntr:, :])
            # Increase number of traces
            ntr += self.__nrec[iexp]

        # Apply phase shift to data to account for t0
        recs = phzshft(recw, owc, dwc, t0)

        return recs
Exemplo n.º 17
0
    def image_data(self,
                   dat,
                   dt,
                   minf,
                   maxf,
                   vel,
                   jf=1,
                   nhx=0,
                   nhy=0,
                   sym=True,
                   nrmax=3,
                   eps=0.0,
                   dtmax=5e-05,
                   wav=None,
                   ntx=0,
                   nty=0,
                   px=0,
                   py=0,
                   nthrds=1,
                   sverb=True,
                   wverb=False) -> np.ndarray:
        """
    3D migration of shot profile data via the one-way wave equation (single-square
    root split-step fourier method). Input data are assumed to follow
    the default geometry (sources and receivers on a regular grid)

    Parameters:
      dat    - input shot profile data [nsy,nsx,nry,nrx,nt]
      dt     - temporal sampling of input data
      minf   - minimum frequency to image in the data [Hz]
      maxf   - maximum frequency to image in the data [Hz]
      vel    - input migration velocity model [nz,ny,nx]
      jf     - frequency decimation factor
      nhx    - number of subsurface offsets in x to compute [0]
      nhy    - number of subsurface offsets in y to compute [0]
      sym    - symmetrize the subsurface offsets [True]
      nrmax  - maximum number of reference velocities [3]
      eps    - stability parameter [0.]
      dtmax  - maximum time error [5e-05]
      wav    - input wavelet [None,assumes an impulse at zero lag]
      ntx    - size of taper in x direction [0]
      nty    - size of taper in y direction [0]
      px     - amount of padding in x direction (samples) [0]
      py     - amount of padding in y direction (samples) [0]
      nthrds - number of OpenMP threads for parallelizing over frequency [1]
      sverb  - verbosity flag for shot progress bar [True]
      wverb  - verbosity flag for frequency progress bar [False]

    Returns:
      an image created from the data [nhy,nhx,nz,ny,nx]
    """
        # Get temporal axis
        nt = dat.shape[-1]

        # Create frequency domain source
        if (wav is None):
            wav = np.zeros(nt, dtype='float32')
            wav[0] = 1.0
        self.__nwo, self.__ow, self.__dw, wfft = self.fft1(wav,
                                                           dt,
                                                           minf=minf,
                                                           maxf=maxf)
        wfftd = wfft[::jf]
        self.__nwc = wfftd.shape[
            0]  # Get the number of frequencies for imaging
        self.__dwc = self.__dw * jf

        if (sverb or wverb):
            print("Frequency axis: nw=%d ow=%f dw=%f" %
                  (self.__nwc, self.__ow, self.__dwc))

        # Create frequency domain data
        _, _, _, dfft = self.fft1(dat, dt, minf=minf, maxf=maxf)
        dfftd = dfft[:, ::jf]
        datt = np.transpose(
            dfftd,
            (0, 1, 4, 2, 3))  # [nsy,nsx,ny,nx,nwc] -> [nsy,nsx,nwc,ny,nx]
        datw = np.ascontiguousarray(
            datt.reshape([self.__nexp, self.__nwc, self.__ny, self.__nx]))

        # Single square root object
        ssf = ssr3(
            self.__nx,
            self.__ny,
            self.__nz,  # Spatial Sizes
            self.__dx,
            self.__dy,
            self.__dz,  # Spatial Samplings
            self.__nwc,
            self.__ow,
            self.__dwc,
            eps,  # Frequency axis
            ntx,
            nty,
            px,
            py,  # Taper and padding
            dtmax,
            nrmax,
            nthrds)  # Reference velocities

        # Compute slowness and reference slownesses
        slo = 1 / vel
        ssf.set_slows(slo)

        # Allocate partial image array
        if (nhx == 0 and nhy == 0):
            imgar = np.zeros([self.__nexp, self.__nz, self.__ny, self.__nx],
                             dtype='float32')
        else:
            if (sym):
                # Create axes
                self.__rnhx = 2 * nhx + 1
                self.__ohx = -nhx * self.__dx
                self.__dhx = self.__dx
                self.__rnhy = 2 * nhy + 1
                self.__ohy = -nhy * self.__dy
                self.__dhy = self.__dy
                # Allocate image array
                imgar = np.zeros([
                    self.__nexp, self.__rnhy, self.__rnhx, self.__nz,
                    self.__ny, self.__nx
                ],
                                 dtype='float32')
            else:
                # Create axes
                self.__rnhx = nhx + 1
                self.__ohx = 0
                self.__dhx = self.__dx
                self.__rnhy = nhy + 1
                self.__ohy = 0
                self.__dhy = self.__dy
                # Allocate image array
                imgar = np.zeros([
                    self.__nexp, self.__rnhy, self.__rnhx, self.__nz,
                    self.__ny, self.__nx
                ],
                                 dtype='float32')
            # Allocate memory necessary for extension
            ssf.set_ext(nhy, nhx, sym)

        # Allocate the source for one shot
        sou = np.zeros([self.__nwc, self.__ny, self.__nx], dtype='complex64')

        # Loop over sources
        k = 0
        for icrd in progressbar(self.__scoords, "nexp:", verb=sverb):
            # Get the source coordinates
            sy = icrd[0]
            sx = icrd[1]
            # Create the source for this shot
            sou[:] = 0.0
            sou[:, sy, sx] = wfftd[:]
            if (nhx == 0 and nhy == 0):
                # Conventional imaging
                ssf.migallw(datw[k], sou, imgar[k], wverb)
            else:
                # Extended imaging
                ssf.migoffallw(datw[k], sou, imgar[k], wverb)
            k += 1

        # Sum over all partial images
        img = np.sum(imgar, axis=0)

        # Free memory for extension
        if (nhx != 0 or nhy != 0):
            ssf.del_ext()

        return img
Exemplo n.º 18
0
def estro_fltangfocdefoc(rimgs,foccnn,dro,oro,nzp=64,nxp=64,strdz=None,strdx=None, # Patching parameters
                         rectz=30,rectx=30,fltthresh=75,fltlbls=None,qcimgs=True,verb=False,
                         fmwrk='torch',device=None):
  """
  Estimates rho by choosing the residually migrated patch that has
  highest angle gather and fault focus probability given by the neural network

  Parameters
    rimgs      - residually migrated angle gathers images [nro,na,nz,nx]
    foccnn     - CNN for determining if angle gather/fault is focused or not
    dro        - residual migration sampling
    oro        - residual migration origin
    nzp        - size of patch in z dimension [64]
    nxp        - size of patch in x dimension [64]
    strdz      - size of stride in z dimension [nzp/2]
    strdx      - size of stride in x dimension [nxp/2]
    rectz      - length of smoother in z dimension [30]
    rectx      - length of smoother in x dimension [30]
    fltlbls    - input fault segmentation labels [None]
    qcimgs     - flag for returning the fault focusing probabilities [nro,nz,nx]
                 and fault patches [nz,nx]
    verb       - verbosity flag [False]
    fmwrk      - deep learning framework to be used for the prediction [torch]
    device     - device for pytorch networks

  Returns an estimate of rho(x,z)
  """
  # Get image dimensions
  nro = rimgs.shape[0]; na = rimgs.shape[1]; nz = rimgs.shape[2]; nx = rimgs.shape[3]

  # Get strides
  if(strdz is None): strdz = int(nzp/2)
  if(strdx is None): strdx = int(nxp/2)

  # Build the Patch Extractors
  pea = PatchExtractor((nro,na,nzp,nxp),stride=(nro,na,strdz,strdx))
  aptch = np.squeeze(pea.extract(rimgs))
  # Flatten patches and make a prediction on each
  numpz = aptch.shape[0]; numpx = aptch.shape[1]
  if(fmwrk == 'torch'):
    aptchf = normalize(aptch.reshape([nro*numpz*numpx,1,na,nzp,nxp]))
    with(torch.no_grad()):
      aptchft = torch.tensor(aptchf)
      focprdt = torch.zeros([nro*numpz*numpx,1])
      for iptch in progressbar(range(aptchf.shape[0]),verb=verb):
        gptch = aptchft[iptch].to(device)
        focprdt[iptch] = torch.sigmoid(foccnn(gptch.unsqueeze(0)))
      focprd = focprdt.cpu().numpy()
  elif(fmwrk == 'tf'):
    aptchf = np.expand_dims(normalize(aptch.reshape([nro*numpz*numpx,na,nzp,nxp])),axis=-1)
    focprd = foccnn.predict(aptchf,verbose=verb)
  elif(fmwrk is None):
    aptchf = normalize(aptch.reshape([nro*numpz*numpx,na,nzp,nxp]))
    focprd = np.zeros([nro*numpz*numpx,1])
    for iptch in progressbar(range(aptchf.shape[0]),verb=verb):
      focprd[iptch] = semblance_power(aptchf[iptch])

  # Assign prediction to entire patch for QC
  focprdptch = np.zeros([numpz*numpx*nro,nzp,nxp])
  for iptch in range(nro*numpz*numpx): focprdptch[iptch,:,:] = focprd[iptch]
  focprdptch = focprdptch.reshape([numpz,numpx,nro,nzp,nxp])

  # Save predictions as a function of rho only
  focprdr = focprd.reshape([numpz,numpx,nro])

  # Output rho image
  pe = PatchExtractor((nzp,nxp),stride=(strdz,strdx))
  rho = np.zeros([nz,nx])
  rhop = pe.extract(rho)

  # Output probabilities
  focprdnrm = np.zeros(focprdptch.shape)
  per = PatchExtractor((nro,nzp,nxp),stride=(nro,strdz,strdx))
  focprdimg = np.zeros([nro,nz,nx])
  _ = per.extract(focprdimg)

  if(fltlbls is None):
    fltptch = np.ones([numpz,numpx,nzp,nxp],dtype='int')
  else:
    pef = PatchExtractor((nzp,nxp),stride=(strdz,strdx))
    fltptch = pef.extract(fltlbls)

  # Estimate rho from angle-fault focus probabilities
  hlfz = int(nzp/2); hlfx = int(nxp/2)
  for izp in range(numpz):
    for ixp in range(numpx):
      if(np.sum(fltptch[izp,ixp]) > fltthresh):
        # Find maximum probability and compute rho
        iprb = focprdptch[izp,ixp,:,hlfz,hlfx]
        rhop[izp,ixp,:,:] = np.argmax(iprb)*dro + oro
        # Normalize across rho within a patch for QC
        if(np.max(focprdptch[izp,ixp,:,hlfz,hlfx]) == 0.0):
          focprdnrm[izp,ixp,:,:,:] = 0.0
        else:
          focprdnrm[izp,ixp,:,:,:] = focprdptch[izp,ixp,:,:,:]/np.max(focprdptch[izp,ixp,:,hlfz,hlfx])
      else:
        rhop[izp,ixp,:,:] = 1.0

  # Reconstruct rho and probabiliites
  rho       = pe.reconstruct(rhop)
  focprdimg = per.reconstruct(focprdnrm.reshape([1,numpz,numpx,nro,nzp,nxp]))

  # Smooth and return rho, fault patches and fault probabilities
  rhosm = smooth(rho.astype('float32'),rect1=rectx,rect2=rectz)
  if(qcimgs):
    focprdimgsm = np.zeros(focprdimg.shape)
    # Smooth the fault focusing for each rho
    for iro in range(nro):
      focprdimgsm[iro] = smooth(focprdimg[iro].astype('float32'),rect1=rectx,rect2=rectz)
    # Return images
    return rhosm,focprdimgsm,focprdr
  else:
    return rhosm
Exemplo n.º 19
0
    def image_data(self,
                   rec,
                   owc,
                   dwc,
                   vel,
                   nhx=0,
                   nhy=0,
                   sym=True,
                   eps=0,
                   nrmax=3,
                   dtmax=5e-05,
                   wav=None,
                   ntx=0,
                   nty=0,
                   px=0,
                   py=0,
                   nthrds=1,
                   sverb=True,
                   wverb=False):
        """
    3D migration of shot profile data via the one-way wave equation (single-square
    root split-step fourier method). Input data are assumed to follow
    the default geometry (sources and receivers on a regular grid)

    Parameters:
      rec    - flattened input shot profile data
      vel    - input migration velocity model [nz,ny,nx]
      jf     - frequency decimation factor
      nhx    - number of subsurface offsets in x to compute [0]
      nhy    - number of subsurface offsets in y to compute [0]
      sym    - symmetrize the subsurface offsets [True]
      nrmax  - maximum number of reference velocities [3]
      dtmax  - maximum time error [5e-05]
      wav    - input wavelet [None,assumes an impulse at zero lag]
      ntx    - size of taper in x direction [0]
      nty    - size of taper in y direction [0]
      px     - amount of padding in x direction (samples) [0]
      py     - amount of padding in y direction (samples) [0]
      nthrds - number of OpenMP threads for parallelizing over frequency [1]
      sverb  - verbosity flag for shot progress bar [True]
      wverb  - verbosity flag for frequency progress bar [False]
      nchnks - number of chunks to distribute over cluster
      client - dask client for distributing work over a cluster

    Returns:
      an image created from the data [nhy,nhx,nz,ny,nx]
    """
        # Make sure data are same size as coordinates
        if (rec.shape[0] != self.__ntr):
            raise Exception(
                "Data must have same number of traces passed to constructor")

        nwc = wav.shape[0]
        if (rec.shape[-1] != nwc):
            raise Exception("Data and wavelet must have same frequency axis")

        # Allocate source and data for one shot
        datw = np.zeros([self.__ny, self.__nx, nwc], dtype='complex64')
        sou = np.zeros([nwc, self.__ny, self.__nx], dtype='complex64')

        # Single square root object
        ssf = ssr3(
            self.__nx,
            self.__ny,
            self.__nz,  # Spatial Sizes
            self.__dx,
            self.__dy,
            self.__dz,  # Spatial Samplings
            nwc,
            owc,
            dwc,
            eps,  # Frequency axis
            ntx,
            nty,
            px,
            py,  # Taper and padding
            dtmax,
            nrmax,
            nthrds)  # Reference velocities and threads

        # Compute slowness and reference slownesses
        slo = 1 / vel
        ssf.set_slows(slo)

        # Allocate partial image array
        if (nhx == 0 and nhy == 0):
            imgtmp = np.zeros([self.__nz, self.__ny, self.__nx],
                              dtype='float32')
            oimg = np.zeros([self.__nz, self.__ny, self.__nx], dtype='float32')
        else:
            if (sym):
                # Create axes
                self.__rnhx = 2 * nhx + 1
                self.__ohx = -nhx * self.__dx
                self.__dhx = self.__dx
                self.__rnhy = 2 * nhy + 1
                self.__ohy = -nhy * self.__dy
                self.__dhy = self.__dy
                imgtmp = np.zeros([
                    self.__rnhy, self.__rnhx, self.__nz, self.__ny, self.__nx
                ],
                                  dtype='float32')
                oimg = np.zeros([
                    self.__rnhy, self.__rnhx, self.__nz, self.__ny, self.__nx
                ],
                                dtype='float32')
            else:
                # Create axes
                self.__rnhx = nhx + 1
                self.__ohx = 0
                self.__dhx = self.__dx
                self.__rnhy = nhy + 1
                self.__ohy = 0
                self.__dhy = self.__dy
                imgtmp = np.zeros([
                    self.__rnhy, self.__rnhx, self.__nz, self.__ny, self.__nx
                ],
                                  dtype='float32')
                oimg = np.zeros([
                    self.__rnhy, self.__rnhx, self.__nz, self.__ny, self.__nx
                ],
                                dtype='float32')
            # Allocate memory necessary for extension
            ssf.set_ext(nhy, nhx, sym, True)
            #ssf.set_ext(nhy,nhx,sym,False)

        # Loop over sources
        ntr = 0
        for iexp in progressbar(range(self.__nexp), "nexp:", verb=sverb):
            # Get the source coordinates
            sy = self.__srcy[iexp]
            sx = self.__srcx[iexp]
            isy = int((sy - self.__oy) / self.__dy + 0.5)
            isx = int((sx - self.__ox) / self.__dx + 0.5)
            # Create the source wavefield for this shot
            sou[:] = 0.0
            sou[:, isy, isx] = wav[:]
            # Inject the data for this shot
            datw[:] = 0.0
            ssf.inject_data(self.__nrec[iexp], self.__recy[ntr:],
                            self.__recx[ntr:], self.__oy, self.__ox,
                            rec[ntr:, :], datw)
            datwt = np.ascontiguousarray(np.transpose(
                datw, (2, 0, 1)))  # [ny,nx,nwc] -> [nwc,ny,nx]
            # Initialize temporary image
            imgtmp[:] = 0.0
            if (nhx == 0 and nhy == 0):
                # Conventional imaging
                ssf.migallw(datwt, sou, imgtmp, wverb)
            else:
                # Extended imaging
                ssf.migoffallw(datwt, sou, imgtmp, wverb)
                #ssf.migoffallwbig(datwt,sou,imgtmp,wverb)
            oimg += imgtmp
            # Increase number of traces
            ntr += self.__nrec[iexp]

        # Free memory for extension
        if (nhx != 0 or nhy != 0):
            ssf.del_ext()

        return oimg
Exemplo n.º 20
0
    def model_data(self,
                   wav,
                   dt,
                   t0,
                   minf,
                   maxf,
                   vel,
                   ref,
                   jf=1,
                   nrmax=3,
                   eps=0.,
                   dtmax=5e-05,
                   time=True,
                   ntx=0,
                   nty=0,
                   px=0,
                   py=0,
                   nthrds=1,
                   sverb=True,
                   wverb=False) -> np.ndarray:
        """
    3D modeling of single scattered (Born) data with the one-way
    wave equation (single square root (SSR), split-step Fourier method).

    Parameters:
      wav    - the input wavelet (source time function) [nt]
      dt     - sampling interval of wavelet
      t0     - time-zero of wavelet (e.g., peak of ricker wavelet)
      minf   - minimum frequency to propagate [Hz]
      maxf   - maximum frequency to propagate [Hz]
      vel    - input velocity model [nz,ny,nx]
      ref    - input reflectivity model [nz,ny,nx]
      jf     - frequency decimation factor [1]
      nrmax  - maximum number of reference velocities [3]
      eps    - stability parameter [0.]
      dtmax  - maximum time error [5e-05]
      time   - return the data back in the time domain [True]
      ntx    - size of taper in x direction (samples) [0]
      nty    - size of taper in y direction (samples) [0]
      px     - amount of padding in x direction (samples)
      py     - amount of padding in y direction (samples)
      nthrds - number of OpenMP threads for parallelizing over frequency [1]
      sverb  - verbosity flag for shot progress bar [True]
      wverb  - verbosity flag for frequency progressbar [False]

    Returns the data at the surface (in time or frequency) [nw,nry,nrx]
    """
        # Save wavelet temporal parameters
        nt = wav.shape[0]
        it0 = int(t0 / dt)

        # Create the input frequency domain source and get original frequency axis
        self.__nwo, self.__ow, self.__dw, wfft = self.fft1(wav,
                                                           dt,
                                                           minf=minf,
                                                           maxf=maxf)
        wfftd = wfft[::jf]
        self.__nwc = wfftd.shape[0]  # Get the number of frequencies to compute
        self.__dwc = jf * self.__dw

        if (sverb or wverb):
            print("Frequency axis: nw=%d ow=%f dw=%f" %
                  (self.__nwc, self.__ow, self.__dwc))

        # Single square root object
        ssf = ssr3(
            self.__nx,
            self.__ny,
            self.__nz,  # Spatial Sizes
            self.__dx,
            self.__dy,
            self.__dz,  # Spatial Samplings
            self.__nwc,
            self.__ow,
            self.__dwc,
            eps,  # Frequency axis
            ntx,
            nty,
            px,
            py,  # Taper and padding
            dtmax,
            nrmax,
            nthrds)  # Reference velocities

        # Compute slowness and reference slownesses
        slo = 1 / vel
        ssf.set_slows(slo)

        # Allocate output data (surface wavefield)
        datw = np.zeros([self.__nexp, self.__nwc, self.__ny, self.__nx],
                        dtype='complex64')

        # Allocate the source for one shot
        sou = np.zeros([self.__nwc, self.__ny, self.__nx], dtype='complex64')

        # Loop over sources
        k = 0
        for icrd in progressbar(self.__scoords, "nexp:", verb=sverb):
            # Get the source coordinates
            sy = icrd[0]
            sx = icrd[1]
            # Create the source for this shot
            sou[:] = 0.0
            sou[:, sy, sx] = wfftd[:]
            # Downward continuation
            ssf.modallw(ref, sou, datw[k], wverb)
            k += 1

        # Reshape output data
        datwr = datw.reshape(
            [self.__nsy, self.__nsx, self.__nwc, self.__ny, self.__nx])

        if (time):
            # Inverse fourier transform
            datt = self.data_f2t(datwr, self.__nwo, self.__ow, self.__dwc, nt,
                                 it0)
            return datt
        else:
            return datwr
Exemplo n.º 21
0
def label_defocused_patches(dptchs,
                            fptchs,
                            fltlbls=None,
                            fprds=None,
                            dprds=None,
                            pixthresh=50,
                            thresh1=0.7,
                            thresh2=0.5,
                            thresh3=0.7,
                            smbthresh=0.4,
                            unsure=True,
                            streamer=True,
                            verb=False,
                            qc=False) -> np.ndarray:
    """
  Attempts to label patches as defocused using the focused equivalent

  Parameters:
    dptchs    - the input defocused patches [nptch,ang,ptchz,ptchx]
    fptchs    - the input focused patches   [nptch,ang,ptchz,ptchx]
    fltlbls   - the input fault labels [None]
    fprds     - the corresponding focused fault predictions [None]
    dprds     - the corresponding defocused fault predictions [None]
    pixthresh - number of fault pixel to determine if patch has fault [50]
    thresh1   - first threshold [0.7]
    thresh2   - second threshold [0.5]
    thresh3   - third threshold [0.7]
    smbthresh - semblance threshold [0.4]
    unsure    - give the unsure label (-1) instead of focused (1) [False]
    streamer  - streamer geometry (one-sided angle gathers) [True]
    verb      - verbosity flag [False]
    qc        - return the computed metrics

  Returns a numpy array of zeros for the defocused patches and -1
  for the others
  """
    # Check that fptchs and dptchs have the same shape
    if (dptchs.shape != fptchs.shape):
        raise Exception(
            "Defocused patches must have same shape as focused patches")

    # Dimensions of inputs
    [nex, na, nzp, nxp] = fptchs.shape
    if (streamer):
        nw = na // 2
    else:
        nw = 0

    # Input segmentation labels
    if (fltlbls is None):
        fltlbls = np.zeros([nzp, nxp], dtype='float32')

    metrics = {
        'fsemb': np.zeros([nex], dtype='float32'),
        'dsemb': np.zeros([nex], dtype='float32'),
        'sembrat': np.zeros([nex], dtype='float32'),
        'fltnum': np.zeros([nex], dtype='float32'),
        'fpvar': np.zeros([nex], dtype='float32'),
        'dpvar': np.zeros([nex], dtype='float32'),
        'pvarrat': np.zeros([nex], dtype='float32'),
        'corrprb': np.zeros([nex], dtype='float32')
    }

    # Output labels
    if (unsure):
        flbls = np.ones(nex, dtype='float32') * -1
    else:
        flbls = np.ones(nex, dtype='float32')

    for iex in progressbar(range(nex), "nex:", verb=verb):
        # Get the example
        cubf = fptchs[iex]
        cubd = dptchs[iex]
        # Angle metrics
        metrics['fsemb'][iex] = semblance_power(cubf[nw:])
        metrics['dsemb'][iex] = semblance_power(cubd[nw:])
        metrics['sembrat'][iex] = metrics['dsemb'][iex] / metrics['fsemb'][iex]
        if (metrics['sembrat'][iex] < smbthresh):
            flbls[iex] = 0
            continue
        metrics['fltnum'][iex] = np.sum(fltlbls)
        if (metrics['fltnum'][iex] > pixthresh):
            fprd = fprds[iex]
            dprd = dprds[iex]
            # Compute fault metrics
            metrics['fpvar'][iex] = varimax(fprd)
            metrics['dpvar'][iex] = varimax(dprd)
            metrics['pvarrat'][iex] = dpvar / fpvar
            metrics['corrprb'][iex] = corrsim(fprd, dprd)
            if (metrics['sembrat'][iex] < thresh1
                    and metrics['pvarrat'][iex] < thresh1):
                flbls[iex] = 0
            elif (metrics['sembrat'][iex] < thresh2
                  or metrics['pvarrat'][iex] < thresh2):
                flbls[iex] = 0
            elif (metrics['corrprb'][iex] < thresh1):
                flbls[iex] = 0
        else:
            if (metrics['sembrat'][iex] < thresh3):
                flbls[iex] = 0

    if (qc):
        return metrics, flbls
    else:
        return flbls
Exemplo n.º 22
0
 # Get work
 chunk = recv_zipped_pickle(socket)
 # If chunk is empty, keep listening
 if(chunk == {}):
   continue
 # If I received something, do some work
 ochunk = {}
 # Create the modeling object
 wei = coordgeomchunk(**chunk[0])
 # Do the modeling
 timg = wei.image_data(**chunk[1])
 # Transfer the data back
 if(len(timg.shape) > 3):
   nhx  = timg.shape[1]
   # Send over the extended image in chunks
   for ihx in progressbar(range(nhx),"transfer",verb=True):
     # Return other parameters if desired
     ochunk['cid'] = chunk[2]
     # Tell server this is the result
     ochunk['msg'] = "result"
     # Send back the result
     ochunk['idx'] = ihx
     ochunk['result'] = timg[0,ihx]
     send_zipped_pickle(socket,ochunk)
     # Receive 'thank you'
     socket.recv()
 else:
   # Return other parameters if desired
   ochunk['cid'] = chunk[2]
   # Tell server this is the result
   ochunk['msg'] = "result"
Exemplo n.º 23
0
def makemoviesbs_mpl(arr1,arr2,odir,ftype='png',qc=False,skip=1,pttag=False,**kwargs):
  """
  Saves each frame on the fast axis to a png for viewing

  Parameters:
    arr1  - first input array (left panel) where the frames are on the fast axis
    arr2  - second input array (right panel) where the frames are on the fast axis
    odir  - the output directory where to save the frames
    ftype - the type (extension) of figure to save [png]
    qc    - look at each frame as it is saved [False]
    skip  - whether to skip frames [1]
    pttag - write the frame number in pretty (unix-friendly) format
  """
  # Check if directory exists
  if(os.path.isdir(odir) == False):
    os.mkdir(odir)
  assert(arr1.shape[2] == arr2.shape[2]),"Both movies must have same number of frames"
  nfr = arr1.shape[2]
  k = 0
  frames = np.arange(0,nfr,skip)
  vmin1 = np.min(arr1); vmax1 = np.max(arr1)
  vmin2 = np.min(arr2); vmax2 = np.max(arr2)
  for ifr in progressbar(frames, "frames"):
    # Setup plot
    f,ax = plt.subplots(1,2,figsize=(kwargs.get("figsize1",15),kwargs.get("figsize2",8)),
        gridspec_kw={'width_ratios': [kwargs.get("wratio1",1), kwargs.get("wratio2",1)]})
    # First plot
    im1 = ax[0].imshow(arr1[:,:,ifr],cmap=kwargs.get("cmap1","gray"),
        extent=[kwargs.get("xmin1",0),kwargs.get("xmax1",arr1.shape[1]),
          kwargs.get("zmax1",arr1.shape[0]),kwargs.get("zmin1",0)],
        vmin=kwargs.get("vmin1",vmin1)*kwargs.get('pclip',1.0),
        vmax=kwargs.get("vmax1",vmax1)*kwargs.get('pclip',1.0),aspect=kwargs.get('aspect1',1.0))
    ax[0].set_xlabel(kwargs.get('xlabel1',''),fontsize=kwargs.get('labelsize',18))
    ax[0].set_ylabel(kwargs.get('ylabel',''),fontsize=kwargs.get('labelsize',18))
    ax[0].tick_params(labelsize=kwargs.get('ticksize',18))
    if('%' in kwargs.get('ttlstring1'),''):
      ax[0].set_title(kwargs.get('ttlstring1','')%(kwargs.get('ottl1',0.0) + kwargs.get('dttl1',1.0)*k),
          fontsize=kwargs.get('labelsize',18))
    else:
      ax[0].set_title(kwargs.get('ttlstring1',''),fontsize=kwargs.get('labelsize',18))
    # Second plot
    im2 = ax[1].imshow(arr2[:,:,ifr],cmap=kwargs.get("cmap2","gray"),
        extent=[kwargs.get("xmin2",0),kwargs.get("xmax2",arr2.shape[1]),
          kwargs.get("zmax2",arr2.shape[0]),kwargs.get("zmin2",0)],
        vmin=kwargs.get("vmin2",vmin2)*kwargs.get('pclip',1.0),
        vmax=kwargs.get("vmax2",vmax2)*kwargs.get('pclip',1.0),aspect=kwargs.get('aspect2',1.0))
    ax[1].set_xlabel(kwargs.get('xlabel2',''),fontsize=kwargs.get('labelsize',18))
    ax[1].set_ylabel(kwargs.get('ylabel2',''),fontsize=kwargs.get('labelsize',18))
    ax[1].tick_params(labelsize=kwargs.get('ticksize',18))
    if('%' in kwargs.get('ttlstring2','')):
      ax[1].set_title(kwargs.get('ttlstring2','')%(kwargs.get('ottl2',0.0) + kwargs.get('dttl2',1.0)*k),
          fontsize=kwargs.get('labelsize',18))
    else:
      ax[1].set_title(kwargs.get('ttlstring2',''),fontsize=kwargs.get('labelsize',18))
    # Color bar
    if(kwargs.get('cbar',False)):
      cbar_ax = f.add_axes([kwargs.get('barx',0.91),kwargs.get('barz',0.12),
        kwargs.get('wbar',0.02),kwargs.get('hbar',0.75)])
      cbar = f.colorbar(im2,cbar_ax,format='%.2f')
      cbar.ax.tick_params(labelsize=kwargs.get('ticksize',18))
      cbar.set_label(kwargs.get('barlabel',''),fontsize=kwargs.get("barlabelsize",18))
      cbar.draw_all()
    # Spacing between plots
    plt.subplots_adjust(wspace=kwargs.get("pltspace",0.2))
    if(pttag):
      tag = create_inttag(k,nfr)
    else:
      tag = str(k)
    plt.savefig(odir+'/'+tag+'.'+ftype,bbox_inches='tight',dpi=kwargs.get("dpi",150))
    k += 1
    if(qc):
      plt.show()
Exemplo n.º 24
0
  def awemva(self,dimg,dat,dt,minf,maxf,vel,jf=1,nrmax=3,eps=0.,dtmax=5e-05,wav=None,
                 ntx=0,nty=0,px=0,py=0,nthrds=1,sverb=True,wverb=False):
    """
    3D Adjoint WEMVA operator

    Parameters:
      dat     - input shot profile data [ntr,nt]
      dt      - temporal sampling of input data
      minf    - minimum frequency to image in the data [Hz]
      maxf    - maximum frequency to image in the data [Hz]
      vel     - input migration velocity model [nz,ny,nx]
      jf      - frequency decimation factor [1]
      nrmax   - maximum number of reference velocities [3]
      eps     - stability parameter [0.]
      dtmax   - maximum time error [5e-05]
      wav     - input wavelet [None,assumes an impulse at zero lag]
      ntx     - size of taper in x direction [0]
      nty     - size of taper in y direction [0]
      px      - amount of padding in x direction (samples) [0]
      py      - amount of padding in y direction (samples) [0]
      nthrds  - number of OpenMP threads for frequency parallelization [1]
      sverb   - verbosity flag for shot progress bar [True]
      wverb   - verbosity flag for frequency progress bar [False]

    Returns:
      a slowness perturbation (adjoint wemva applied to image perturbation) [nz,ny,nx]
    """
    # Make sure data are same size as coordinates
    if(dat.shape[0] != self.__ntr):
      raise Exception("Data must have same number of traces passed to constructor")

    # Get temporal axis
    nt = dat.shape[-1]

    # Create frequency domain source
    if(wav is None):
      wav    = np.zeros(nt,dtype='float32')
      wav[0] = 1.0
    self.__nwo,self.__ow,self.__dw,wfft = fft1(wav,dt,minf=minf,maxf=maxf)
    wfftd = wfft[::jf]
    self.__nwc = wfftd.shape[0] # Get the number of frequencies for imaging
    self.__dwc = self.__dw*jf

    if(sverb or wverb): print("Frequency axis: nw=%d ow=%f dw=%f"%(self.__nwc,self.__ow,self.__dwc))

    # Create frequency domain data
    _,_,_,dfft = fft1(dat,dt,minf=minf,maxf=maxf)
    dfftd = dfft[:,::jf]
    # Allocate the data for one shot
    datw = np.zeros([self.__ny,self.__nx,self.__nwc],dtype='complex64')
    # Allocate the source for one shot
    sou = np.zeros([self.__nwc,self.__ny,self.__nx],dtype='complex64')

    # Single square root object
    ssf = ssr3(self.__nx ,self.__ny,self.__nz ,     # Spatial Sizes
               self.__dx ,self.__dy,self.__dz ,     # Spatial Samplings
               self.__nwc,self.__ow,self.__dwc,eps, # Frequency axis
               ntx,nty,px,py,                       # Taper and padding
               dtmax,nrmax,nthrds)                  # Reference velocities and threads

    # Compute slowness and reference slownesses
    slo = 1/vel
    ssf.set_slows(slo)

    # Allocate temporary partial image
    dslotmp = np.zeros([self.__nz,self.__ny,self.__nx],dtype='complex64')
    odslo   = np.zeros([self.__nz,self.__ny,self.__nx],dtype='complex64')

    # Loop over sources
    ntr = 0
    for iexp in progressbar(range(self.__nexp),"nexp:",verb=sverb):
      # Get the source coordinates
      sy = self.__srcys[iexp]; sx = self.__srcxs[iexp]
      isy = int((sy-self.__oy)/self.__dy+0.5); isx = int((sx-self.__ox)/self.__dx+0.5)
      # Create the source wavefield for this shot
      sou[:] = 0.0
      sou[:,isy,isx]  = wfftd[:]
      # Inject the data for this shot
      datw[:] = 0.0
      ssf.inject_data(self.__nrec[iexp],self.__recys[ntr:],self.__recxs[ntr:],self.__oy,self.__ox,dfftd[ntr:,:],datw)
      datwt = np.ascontiguousarray(np.transpose(datw,(2,0,1))) # [ny,nx,nwc] -> [nwc,ny,nx]
      # Initialize temporary image
      dslotmp[:] = 0.0
      # Adjoint WEMVA
      ssf.awemvaallw(sou,datwt,dslotmp,dimg,verb=wverb)
      odslo += dslotmp
      # Increase number of traces
      ntr += self.__nrec[iexp]

    return np.real(odslo)
Exemplo n.º 25
0
  def image_data(self,dat,dt,minf,maxf,vel,jf=1,nhx=0,nhy=0,sym=True,nrmax=3,eps=0.,dtmax=5e-05,wav=None,
                 ntx=0,nty=0,px=0,py=0,nthrds=1,sverb=True,wverb=False):
    """
    3D migration of shot profile data via the one-way wave equation (single-square
    root split-step fourier method).

    Parameters:
      dat     - input shot profile data [ntr,nt]
      dt      - temporal sampling of input data
      minf    - minimum frequency to image in the data [Hz]
      maxf    - maximum frequency to image in the data [Hz]
      vel     - input migration velocity model [nz,ny,nx]
      jf      - frequency decimation factor [1]
      nhx     - number of subsurface offsets in x to compute [0]
      nhy     - number of subsurface offsets in y to compute [0]
      sym     - symmetrize the subsurface offsets [True]
      nrmax   - maximum number of reference velocities [3]
      eps     - stability parameter [0.]
      dtmax   - maximum time error [5e-05]
      wav     - input wavelet [None,assumes an impulse at zero lag]
      ntx     - size of taper in x direction [0]
      nty     - size of taper in y direction [0]
      px      - amount of padding in x direction (samples) [0]
      py      - amount of padding in y direction (samples) [0]
      nthrds  - number of OpenMP threads for frequency parallelization [1]
      sverb   - verbosity flag for shot progress bar [True]
      wverb   - verbosity flag for frequency progress bar [False]

    Returns:
      an image created from the data [nhy,nhx,nz,ny,nx]
    """
    # Make sure data are same size as coordinates
    if(dat.shape[0] != self.__ntr):
      raise Exception("Data must have same number of traces passed to constructor")

    # Get temporal axis
    nt = dat.shape[-1]

    # Create frequency domain source
    if(wav is None):
      wav    = np.zeros(nt,dtype='float32')
      wav[0] = 1.0
    self.__nwo,self.__ow,self.__dw,wfft = fft1(wav,dt,minf=minf,maxf=maxf)
    wfftd = wfft[::jf]
    self.__nwc = wfftd.shape[0] # Get the number of frequencies for imaging
    self.__dwc = self.__dw*jf

    if(sverb or wverb): print("Frequency axis: nw=%d ow=%f dw=%f"%(self.__nwc,self.__ow,self.__dwc))

    # Create frequency domain data
    _,_,_,dfft = fft1(dat,dt,minf=minf,maxf=maxf)
    dfftd = dfft[:,::jf]
    # Allocate the data for one shot
    datw = np.zeros([self.__ny,self.__nx,self.__nwc],dtype='complex64')
    # Allocate the source for one shot
    sou = np.zeros([self.__nwc,self.__ny,self.__nx],dtype='complex64')

    # Single square root object
    ssf = ssr3(self.__nx ,self.__ny,self.__nz ,     # Spatial Sizes
               self.__dx ,self.__dy,self.__dz ,     # Spatial Samplings
               self.__nwc,self.__ow,self.__dwc,eps, # Frequency axis
               ntx,nty,px,py,                       # Taper and padding
               dtmax,nrmax,nthrds)                  # Reference velocities and threads

    # Compute slowness and reference slownesses
    slo = 1/vel
    ssf.set_slows(slo)

    # Allocate partial image array
    if(nhx == 0 and nhy == 0):
      imgtmp = np.zeros([self.__nz,self.__ny,self.__nx],dtype='float32')
      oimg   = np.zeros([self.__nz,self.__ny,self.__nx],dtype='float32')
    else:
      if(sym):
        # Create axes
        self.__rnhx = 2*nhx+1; self.__ohx = -nhx*self.__dx; self.__dhx = self.__dx
        self.__rnhy = 2*nhy+1; self.__ohy = -nhy*self.__dy; self.__dhy = self.__dy
        imgtmp = np.zeros([self.__rnhy,self.__rnhx,self.__nz,self.__ny,self.__nx],dtype='float32')
        oimg   = np.zeros([self.__rnhy,self.__rnhx,self.__nz,self.__ny,self.__nx],dtype='float32')
      else:
        # Create axes
        self.__rnhx = nhx+1; self.__ohx = 0; self.__dhx = self.__dx
        self.__rnhy = nhy+1; self.__ohy = 0; self.__dhy = self.__dy
        imgtmp = np.zeros([self.__rnhy,self.__rnhx,self.__nz,self.__ny,self.__nx],dtype='float32')
        oimg   = np.zeros([self.__rnhy,self.__rnhx,self.__nz,self.__ny,self.__nx],dtype='float32')
      # Allocate memory necessary for extension
      ssf.set_ext(nhy,nhx,sym)

    # Loop over sources
    ntr = 0
    for iexp in progressbar(range(self.__nexp),"nexp:",verb=sverb):
      # Get the source coordinates
      sy = self.__srcys[iexp]; sx = self.__srcxs[iexp]
      isy = int((sy-self.__oy)/self.__dy+0.5); isx = int((sx-self.__ox)/self.__dx+0.5)
      # Create the source wavefield for this shot
      sou[:] = 0.0
      sou[:,isy,isx]  = wfftd[:]
      # Inject the data for this shot
      datw[:] = 0.0
      ssf.inject_data(self.__nrec[iexp],self.__recys[ntr:],self.__recxs[ntr:],self.__oy,self.__ox,dfftd[ntr:,:],datw)
      datwt = np.ascontiguousarray(np.transpose(datw,(2,0,1))) # [ny,nx,nwc] -> [nwc,ny,nx]
      # Initialize temporary image
      imgtmp[:] = 0.0
      if(nhx == 0 and nhy == 0):
        # Conventional imaging
        ssf.migallw(datwt,sou,imgtmp,wverb)
      else:
        # Extended imaging
        ssf.migoffallw(datwt,sou,imgtmp,wverb)
      oimg += imgtmp
      # Increase number of traces
      ntr += self.__nrec[iexp]

    # Free memory for extension
    if(nhx != 0 or nhy != 0):
      ssf.del_ext()

    return oimg
Exemplo n.º 26
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
Exemplo n.º 27
0
    def awemva(self,
               dimg,
               dat,
               dt,
               minf,
               maxf,
               vel,
               jf=1,
               nrmax=3,
               eps=0.0,
               dtmax=5e-05,
               wav=None,
               ntx=0,
               nty=0,
               px=0,
               py=0,
               nthrds=1,
               sverb=True,
               wverb=False) -> np.ndarray:
        """
    Applies the forward WEMVA operator

    Parameters:
      dimg   - the input image perturbation
      dat    - the input data
      dt     - temporal sampling interval
      minf   - minimum frequency to image in the data [Hz]
      maxf   - maximim frequency to image in the data [Hz]
      vel    - input migration velocity model [nz,ny,nx]
      jf     - frequency decimation factor [1]
      nrmax  - maximum number of reference velocities [3]
      eps    - stability parameter [0.]
      dtmax  - maximum time error [5e-05]
      wav    - input wavelet [None,assumes an impulse at zero lag]
      ntx    - size of taper in x direction [0]
      nty    - size of taper in y direction [0]
      px     - amount of padding in x direction (samples) [0]
      py     - amount of padding in y direction (samples) [0]
      nthrds - number of OpenMP threads for parallelizing over frequency [1]
      sverb  - verbosity flag for shot progress bar [True]
      wverb  - verbosity flag for frequency progress bar [False]

    Returns:
      a slowness perturbation (adjoint wemva applied to image) [nz,ny,nx]
    """
        # Get temporal axis
        nt = dat.shape[-1]

        # Create frequency domain source
        if (wav is None):
            wav = np.zeros(nt, dtype='float32')
            wav[0] = 1.0
        self.__nwo, self.__ow, self.__dw, wfft = self.fft1(wav,
                                                           dt,
                                                           minf=minf,
                                                           maxf=maxf)
        wfftd = wfft[::jf]
        self.__nwc = wfftd.shape[
            0]  # Get the number of frequencies for imaging
        self.__dwc = self.__dw * jf

        if (sverb or wverb):
            print("Frequency axis: nw=%d ow=%f dw=%f" %
                  (self.__nwc, self.__ow, self.__dwc))

        # Create frequency domain data
        _, _, _, dfft = self.fft1(dat, dt, minf=minf, maxf=maxf)
        dfftd = dfft[:, ::jf]
        datt = np.transpose(
            dfftd,
            (0, 1, 4, 2, 3))  # [nsy,nsx,ny,nx,nwc] -> [nsy,nsx,nwc,ny,nx]
        datw = np.ascontiguousarray(
            datt.reshape([self.__nexp, self.__nwc, self.__ny, self.__nx]))

        # Single square root object
        ssf = ssr3(
            self.__nx,
            self.__ny,
            self.__nz,  # Spatial Sizes
            self.__dx,
            self.__dy,
            self.__dz,  # Spatial Samplings
            self.__nwc,
            self.__ow,
            self.__dwc,
            eps,  # Frequency axis
            ntx,
            nty,
            px,
            py,  # Taper and padding
            dtmax,
            nrmax,
            nthrds)  # Reference velocities

        # Compute slowness and reference slownesses
        slo = 1 / vel
        ssf.set_slows(slo)

        dsloar = np.zeros([self.__nexp, self.__nz, self.__ny, self.__nx],
                          dtype='complex64')

        # Allocate the source for one shot
        sou = np.zeros([self.__nwc, self.__ny, self.__nx], dtype='complex64')

        # Loop over sources
        k = 0
        for icrd in progressbar(self.__scoords, "nexp:", verb=sverb):
            # Get the source coordinates
            sy = icrd[0]
            sx = icrd[1]
            # Create the source for this shot
            sou[:] = 0.0
            sou[:, sy, sx] = wfftd[:]
            ssf.awemvaallw(sou, datw[k], dsloar[k], dimg, verb=wverb)
            k += 1

        # Sum over all partial images
        dslo = np.sum(dsloar, axis=0)

        return np.real(dslo)
Exemplo n.º 28
0
  def model_data(self,wav,dt,t0,minf,maxf,vel,ref,jf=1,nrmax=3,eps=0.,dtmax=5e-05,time=True,
                 ntx=0,nty=0,px=0,py=0,nthrds=1,sverb=True,wverb=False):
    """
    3D modeling of single scattered (Born) data with the one-way
    wave equation (single square root (SSR), split-step Fourier method).

    Parameters:
      wav    - the input wavelet (source time function) [nt]
      dt     - sampling interval of wavelet
      t0     - time-zero of wavelet (e.g., peak of ricker wavelet)
      minf   - minimum frequency to propagate [Hz]
      maxf   - maximum frequency to propagate [Hz]
      vel    - input velocity model [nz,ny,nx]
      ref    - input reflectivity model [nz,ny,nx]
      jf     - frequency decimation factor
      nrmax  - maximum number of reference velocities [3]
      eps    - stability parameter [0.]
      dtmax  - maximum time error [5e-05]
      time   - return the data back in the time domain [True]
      ntx    - size of taper in x direction (samples) [0]
      nty    - size of taper in y direction (samples) [0]
      px     - amount of padding in x direction (samples)
      py     - amount of padding in y direction (samples)
      nthrds - number of OpenMP threads to use for frequency parallelization [1]
      sverb  - verbosity flag for shot progress bar [True]
      wverb  - verbosity flag for frequency progress bar [False]

    Returns:
      the data at the surface (in time or frequency) [nw,nry,nrx]
    """
    # Save wavelet temporal parameters
    nt = wav.shape[0]; it0 = int(t0/dt)

    # Create the input frequency domain source and get original frequency axis
    self.__nwo,self.__ow,self.__dw,wfft = fft1(wav,dt,minf=minf,maxf=maxf)
    wfftd = wfft[::jf]
    self.__nwc = wfftd.shape[0] # Get the number of frequencies to compute
    self.__dwc = jf*self.__dw

    if(sverb or wverb): print("Frequency axis: nw=%d ow=%f dw=%f"%(self.__nwc,self.__ow,self.__dwc))

    # Single square root object
    ssf = ssr3(self.__nx ,self.__ny,self.__nz ,     # Spatial Sizes
               self.__dx ,self.__dy,self.__dz ,     # Spatial Samplings
               self.__nwc,self.__ow,self.__dwc,eps, # Frequency axis
               ntx,nty,px,py,                       # Taper and padding
               dtmax,nrmax,nthrds)                  # Reference velocities and threads

    # Compute slowness and reference slownesses
    slo = 1/vel
    ssf.set_slows(slo)

    # Allocate output data (surface wavefield) and receiver data
    datw  = np.zeros([self.__nwc,self.__ny,self.__nx],dtype='complex64')
    recw  = np.zeros([self.__ntr,self.__nwc],dtype='complex64')

    # Allocate the source for one shot
    sou = np.zeros([self.__nwc,self.__ny,self.__nx],dtype='complex64')

    # Loop over sources
    ntr = 0
    for iexp in progressbar(range(self.__nexp),"nexp:",verb=sverb):
      # Get the source coordinates
      sy = self.__srcys[iexp]; sx = self.__srcxs[iexp]
      isy = int((sy-self.__oy)/self.__dy+0.5); isx = int((sx-self.__ox)/self.__dx+0.5)
      # Create the source for this shot
      sou[:] = 0.0
      sou[:,isy,isx]  = wfftd[:]
      # Downward continuation
      datw[:] = 0.0
      ssf.modallw(ref,sou,datw,wverb)
      # Restrict to receiver locations
      datwt = np.ascontiguousarray(np.transpose(datw,(1,2,0)))  # [nwc,ny,nx] -> [ny,nx,nwc]
      ssf.restrict_data(self.__nrec[iexp],self.__recys[ntr:],self.__recxs[ntr:],self.__oy,self.__ox,datwt,recw[ntr:,:])
      # Increase number of traces
      ntr += self.__nrec[iexp]

    if(time):
      rect = ifft1(recw,self.__nwo,self.__ow,self.__dw,nt,it0)
      return rect
    else:
      return recw
Exemplo n.º 29
0
def off2angkzx(off,
               ohx,
               dhx,
               dz,
               ohy=0.0,
               dhy=1.0,
               oz=0.0,
               na=None,
               amax=60,
               oa=None,
               da=None,
               transp=False,
               eps=1.0,
               nthrds=4,
               cverb=False,
               rverb=False):
    """
  Converts subsurface offset gathers to openeing angle gathers via a
  radial trace transform in the wavenumber domain

  Parameters
    off    - subsurface offset gathers of shape [nro,nhy,nhx,nz,ny,nx] (nro is optional)
    ohx    - origin of subsurface offset axis
    dhx    - sampling of subsurface offset axis
    dz     - sampling in depth
    oz     - depth origin [0.0]
    ohy    - origin of y-subsurface offsets [0.0]
    dhy    - sampling of y-subsurface offsets [1.0]
    na     - number of angles [nhx]
    amax   - maximum angle [60 degrees]
    oa     - origin of angle axis (not needed if na and amax specified)
    da     - spacing on angle axis (not needed if na and amax specified)
    transp - input has shape [nro,nhy,nhx,ny,nx,nz] instead of assumed shape [False]
    eps    - regularization parameter (larger will enforce smoother output) [1.0]
    nthrds - number of OpenMP threads to parallelize over gathers [4]
    rverb  - residual migration verbosity flag [False]
    cverb  - gather conversion verbosity flag [False]

  Returns the converted angle gathers of shape [nro,ny,nx,naz,na,nz]
  """
    # Handle case of 2D residual migration [nro,nhx,nx,nz]
    if (len(off.shape) == 4):
        # Get dimensions
        [nro, nhx, nx, nz] = off.shape
        nhy = 1
        ny = 1
        off = off.reshape([nro, nhy, nhx, ny, nx, nz])
        # [nro,nhy,nhx,ny,nx,nz] -> [nro,ny,nx,nz,nhy,nhx]
        offi = np.ascontiguousarray(np.transpose(off, (0, 3, 4, 5, 1, 2)))
    if (len(off.shape) == 5):
        nro = 1
        if (transp == False):
            # Get dimensions
            [nhy, nhx, nz, ny, nx] = off.shape
            offe = np.expand_dims(off, axis=0)
            # Transpose to correct shape
            # [nro,nhy,nhx,nz,ny,nx] -> [nro,ny,nx,nz,nhy,nhx]
            offi = np.ascontiguousarray(np.transpose(offe, (0, 4, 5, 3, 1, 2)))
        else:
            # Get dimensions
            [nhy, nhx, ny, nx, nz] = off.shape
            offe = np.expand_dims(off, axis=0)
            # Transpose to correct shape
            # [nro,nhy,nhx,ny,nx,nz] -> [nro,ny,nx,nz,nhy,nhx]
            offi = np.ascontiguousarray(np.transpose(offe, (0, 3, 4, 5, 1, 2)))

    # Pad input based on desired number of angles
    if (na is None):
        na = nhx
    paddims = [(0, 0)] * (offi.ndim - 1)
    paddims.append((0, na - nhx))
    offip = np.pad(offi, paddims, mode='constant').astype('complex64')
    ang = np.zeros(offip.shape, dtype='complex64')

    # Compute angle axis
    oa = -amax
    da = 2 * amax / na

    # Loop over rho
    for iro in progressbar(range(nro), "nrho:", verb=rverb):
        convert2angkzkykx(
            nx * ny,  # Number of gathers
            nz,
            oz,
            dz,
            nhy,
            ohy,
            dhy,
            na,
            ohx,
            dhx,
            oa,
            da,  # Axes of input and output
            offip[iro],
            ang[iro],
            eps,
            nthrds,
            cverb)  # Input and output and parameters

    # Transpose, window and return
    if (transp):
        if (nro > 1):
            angw = ang[:, 0, :, :,
                       0, :]  # [nro,ny,nx,nz,naz,na] -> [nro,nx,nz,na]
            ango = np.transpose(
                angw, (0, 1, 3, 2))  # [nro,nx,nz,na] -> [nro,nx,na,nz]
        else:
            angw = ang[0]
            ango = np.transpose(
                angw,
                (0, 1, 3, 4, 2))  # [ny,nx,nz,naz,na] -> [ny,nx,naz,na,nz]
    else:
        if (nro > 1):
            angw = ang[:, 0, :, :,
                       0, :]  # [nro,ny,nx,nz,naz,na] -> [nro,nx,nz,na]
            ango = np.transpose(
                angw, (0, 3, 2, 1))  # [nro,nx,nz,na] -> [nro,na,nz,nx]
        else:
            angw = ang[0]
            ango = np.transpose(
                angw,
                (3, 4, 2, 0, 1))  # [ny,nx,nz,naz,na] -> [naz,na,nz,ny,nx]

    return np.real(np.ascontiguousarray(ango))
Exemplo n.º 30
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