Example #1
0
def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
    """
        Load in endpoints and survey specifications to generate Tx, Rx location
        stations.

        Assumes flat topo for now...

        Input:
        :param endl -> input endpoints [x1, y1, z1, x2, y2, z2]
        :object mesh -> SimPEG mesh object
        :switch stype -> "dpdp" (dipole-dipole) | "pdp" (pole-dipole) | 'gradient'
        : param a, n -> pole seperation, number of rx dipoles per tx

        Output:
        :param Tx, Rx -> List objects for each tx location
            Lines: P1x, P1y, P1z, P2x, P2y, P2z

        Created on Wed December 9th, 2015

        @author: dominiquef
        !! Require clean up to deal with DCsurvey
    """

    from SimPEG import np

    def xy_2_r(x1, x2, y1, y2):
        r = np.sqrt(np.sum((x2 - x1)**2 + (y2 - y1)**2))
        return r

    ## Evenly distribute electrodes and put on surface
    # Mesure survey length and direction
    dl_len = xy_2_r(endl[0, 0], endl[1, 0], endl[0, 1], endl[1, 1])

    dl_x = (endl[1, 0] - endl[0, 0]) / dl_len
    dl_y = (endl[1, 1] - endl[0, 1]) / dl_len

    nstn = np.floor(dl_len / a)

    # Compute discrete pole location along line
    stn_x = endl[0, 0] + np.array(range(int(nstn))) * dl_x * a
    stn_y = endl[0, 1] + np.array(range(int(nstn))) * dl_y * a

    if mesh.dim == 2:
        ztop = mesh.vectorNy[-1]
        # Create line of P1 locations
        M = np.c_[stn_x, np.ones(nstn).T * ztop]
        # Create line of P2 locations
        N = np.c_[stn_x + a * dl_x, np.ones(nstn).T * ztop]

    elif mesh.dim == 3:
        ztop = mesh.vectorNz[-1]
        # Create line of P1 locations
        M = np.c_[stn_x, stn_y, np.ones(nstn).T * ztop]
        # Create line of P2 locations
        N = np.c_[stn_x + a * dl_x, stn_y + a * dl_y, np.ones(nstn).T * ztop]

    ## Build list of Tx-Rx locations depending on survey type
    # Dipole-dipole: Moving tx with [a] spacing -> [AB a MN1 a MN2 ... a MNn]
    # Pole-dipole: Moving pole on one end -> [A a MN1 a MN2 ... MNn a B]
    SrcList = []

    if stype != 'gradient':

        for ii in range(0, int(nstn) - 1):

            if stype == 'dipole-dipole':
                tx = np.c_[M[ii, :], N[ii, :]]
            elif stype == 'pole-dipole':
                tx = np.c_[M[ii, :], M[ii, :]]
            else:
                raise Exception(
                    'The stype must be "dipole-dipole" or "pole-dipole"')

            # Rx.append(np.c_[M[ii+1:indx,:],N[ii+1:indx,:]])

            # Current elctrode seperation
            AB = xy_2_r(tx[0, 1], endl[1, 0], tx[1, 1], endl[1, 1])

            # Number of receivers to fit
            nstn = np.min([np.floor((AB - b) / a), n])

            # Check if there is enough space, else break the loop
            if nstn <= 0:
                continue

            # Compute discrete pole location along line
            stn_x = N[ii, 0] + dl_x * b + np.array(range(int(nstn))) * dl_x * a
            stn_y = N[ii, 1] + dl_y * b + np.array(range(int(nstn))) * dl_y * a

            # Create receiver poles

            if mesh.dim == 3:
                # Create line of P1 locations
                P1 = np.c_[stn_x, stn_y, np.ones(nstn).T * ztop]
                # Create line of P2 locations
                P2 = np.c_[stn_x + a * dl_x, stn_y + a * dl_y,
                           np.ones(nstn).T * ztop]
                rxClass = DC.Rx.Dipole(P1, P2)

            elif mesh.dim == 2:
                # Create line of P1 locations
                P1 = np.c_[stn_x, np.ones(nstn).T * ztop]
                # Create line of P2 locations
                P2 = np.c_[stn_x + a * dl_x, np.ones(nstn).T * ztop]
                rxClass = DC.Rx.Dipole_ky(P1, P2)

            if stype == 'dipole-dipole':
                srcClass = DC.Src.Dipole([rxClass], M[ii, :], N[ii, :])
            elif stype == 'pole-dipole':
                srcClass = DC.Src.Pole([rxClass], M[ii, :])
            SrcList.append(srcClass)

    elif stype == 'gradient':

        # Gradient survey only requires Tx at end of line and creates a square
        # grid of receivers at in the middle at a pre-set minimum distance

        # Get the edge limit of survey area
        min_x = endl[0, 0] + dl_x * b
        min_y = endl[0, 1] + dl_y * b

        max_x = endl[1, 0] - dl_x * b
        max_y = endl[1, 1] - dl_y * b

        box_l = np.sqrt((min_x - max_x)**2 + (min_y - max_y)**2)
        box_w = box_l / 2.

        nstn = np.floor(box_l / a)

        # Compute discrete pole location along line
        stn_x = min_x + np.array(range(int(nstn))) * dl_x * a
        stn_y = min_y + np.array(range(int(nstn))) * dl_y * a

        # Define number of cross lines
        nlin = int(np.floor(box_w / a))
        lind = range(-nlin, nlin + 1)

        ngrad = nstn * len(lind)

        rx = np.zeros([ngrad, 6])
        for ii in range(len(lind)):

            # Move line in perpendicular direction by dipole spacing
            lxx = stn_x - lind[ii] * a * dl_y
            lyy = stn_y + lind[ii] * a * dl_x

            M = np.c_[lxx, lyy, np.ones(nstn).T * ztop]
            N = np.c_[lxx + a * dl_x, lyy + a * dl_y, np.ones(nstn).T * ztop]
            rx[(ii * nstn):((ii + 1) * nstn), :] = np.c_[M, N]

            if mesh.dim == 3:
                rxClass = DC.Rx.Dipole(rx[:, :3], rx[:, 3:])
            elif mesh.dim == 2:
                M = M[:, [0, 2]]
                N = N[:, [0, 2]]
                rxClass = DC.Rx.Dipole_ky(rx[:, [0, 2]], rx[:, [3, 5]])
            srcClass = DC.Src.Dipole([rxClass], M[0, :], N[-1, :])
        SrcList.append(srcClass)
    else:
        print """stype must be either 'pole-dipole', 'dipole-dipole' or 'gradient'. """

    return SrcList
Example #2
0
# Add z coordinate
nz = mesh.vectorNz
endp = np.c_[np.asarray(temp), np.ones(2).T * nz[-1]]

# Create dipole survey receivers and plot
nrx = 10
ab = 40
a = 20

# Evenly distribute transmitters for now and put on surface
dplen = np.sqrt(np.sum((endp[1, :] - endp[0, :])**2))
dp_x = (endp[1, 0] - endp[0, 0]) / dplen
dp_y = (endp[1, 1] - endp[0, 1]) / dplen

nstn = np.floor(dplen / ab)

stn_x = endp[0, 0] + np.cumsum(np.ones(nstn) * dp_x * ab)
stn_y = endp[0, 1] + np.cumsum(np.ones(nstn) * dp_y * ab)

plt.scatter(stn_x, stn_y, s=100, c='w')

M = np.c_[stn_x - a * dp_x, stn_y - a * dp_y, np.ones(nstn).T * nz[-1]]
N = np.c_[stn_x + a * dp_x, stn_y + a * dp_y, np.ones(nstn).T * nz[-1]]

plt.scatter(M[:, 0], M[:, 1], s=10, c='r')
plt.scatter(N[:, 0], N[:, 1], s=10, c='b')

#%% Create inversion parameter

Rx = DC.RxDipole(M, N)
Example #3
0
def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
    
    from SimPEG import np
    import re
    """
        Load in endpoints and survey specifications to generate Tx, Rx location
        stations.
        
        Assumes flat topo for now...
    
        Input:
        :param endl -> input endpoints [x1, y1, z1, x2, y2, z2]
        :object mesh -> SimPEG mesh object
        :switch stype -> "dpdp" (dipole-dipole) | "pdp" (pole-dipole) | 'gradient'
        : param a, n -> pole seperation, number of rx dipoles per tx
        
        Output:
        :param Tx, Rx -> List objects for each tx location
            Lines: P1x, P1y, P1z, P2x, P2y, P2z
        
        Created on Wed December 9th, 2015
    
        @author: dominiquef
    
    """
    def xy_2_r(x1,x2,y1,y2):
        r = np.sqrt( np.sum((x2 - x1)**2 + (y2 - y1)**2) )
        return r 
        
    ## Evenly distribute electrodes and put on surface
    # Mesure survey length and direction
    dl_len = xy_2_r(endl[0,0],endl[1,0],endl[0,1],endl[1,1])
    
    dl_x = ( endl[1,0] - endl[0,0] ) / dl_len
    dl_y = ( endl[1,1] - endl[0,1] ) / dl_len
       
    nstn = np.floor( dl_len / a )
    
    # Compute discrete pole location along line
    stn_x = endl[0,0] + np.array(range(int(nstn)))*dl_x*a
    stn_y = endl[0,1] + np.array(range(int(nstn)))*dl_y*a
    
    # Create line of P1 locations
    M = np.c_[stn_x, stn_y, np.ones(nstn).T*mesh.vectorNz[-1]]
    
    # Create line of P2 locations
    N = np.c_[stn_x+a*dl_x, stn_y+a*dl_y, np.ones(nstn).T*mesh.vectorNz[-1]]
    
    ## Build list of Tx-Rx locations depending on survey type
    # Dipole-dipole: Moving tx with [a] spacing -> [AB a MN1 a MN2 ... a MNn]
    # Pole-dipole: Moving pole on one end -> [A a MN1 a MN2 ... MNn a B]
    Tx = []
    Rx = []
    
    if not re.match(stype,'gradient'):
        
        for ii in range(0, int(nstn)-1): 
            
            
            if re.match(stype,'dpdp'):
                tx = np.c_[M[ii,:],N[ii,:]]
            elif re.match(stype,'pdp'):
                tx = np.c_[M[ii,:],M[ii,:]]
                
            #Rx.append(np.c_[M[ii+1:indx,:],N[ii+1:indx,:]])
            
            # Current elctrode seperation
            AB = xy_2_r(tx[0,1],endl[1,0],tx[1,1],endl[1,1])
            
            # Number of receivers to fit
            nstn = np.min([np.floor( (AB - b) / a ) , n])
            
            # Check if there is enough space, else break the loop
            if nstn <= 0:
                continue
            
            # Compute discrete pole location along line
            stn_x = N[ii,0] + dl_x*b + np.array(range(int(nstn)))*dl_x*a
            stn_y = N[ii,1] + dl_y*b + np.array(range(int(nstn)))*dl_y*a
            
            # Create receiver poles
            # Create line of P1 locations
            P1 = np.c_[stn_x, stn_y, np.ones(nstn).T*mesh.vectorNz[-1]]
            
            # Create line of P2 locations
            P2 = np.c_[stn_x+a*dl_x, stn_y+a*dl_y, np.ones(nstn).T*mesh.vectorNz[-1]]
            
            Rx.append(np.c_[P1,P2])
            Tx.append(tx)            
            
#==============================================================================
#     elif re.match(stype,'dpdp'):
#         
#         for ii in range(0, int(nstn)-2):  
#             
#             indx = np.min([ii+n+1,nstn])
#             Tx.append(np.c_[M[ii,:],N[ii,:]])
#             Rx.append(np.c_[M[ii+2:indx,:],N[ii+2:indx,:]])
#==============================================================================
            
    elif re.match(stype,'gradient'):
        
        # Gradient survey only requires Tx at end of line and creates a square
        # grid of receivers at in the middle at a pre-set minimum distance
        Tx.append(np.c_[M[0,:],N[-1,:]])
              
        # Get the edge limit of survey area
        min_x = endl[0,0] + dl_x * b
        min_y = endl[0,1] + dl_y * b
            
        max_x = endl[1,0] - dl_x * b
        max_y = endl[1,1] - dl_y * b
        
        box_l = np.sqrt( (min_x - max_x)**2 + (min_y - max_y)**2 )
        box_w = box_l/2.
        
        nstn = np.floor( box_l / a )
        
        # Compute discrete pole location along line
        stn_x = min_x + np.array(range(int(nstn)))*dl_x*a
        stn_y = min_y + np.array(range(int(nstn)))*dl_y*a
        
        # Define number of cross lines
        nlin = int(np.floor( box_w / a ))
        lind = range(-nlin,nlin+1) 
        
        ngrad = nstn * len(lind)
        
        rx = np.zeros([ngrad,6])
        for ii in range( len(lind) ):
            
            # Move line in perpendicular direction by dipole spacing
            lxx = stn_x - lind[ii]*a*dl_y
            lyy = stn_y + lind[ii]*a*dl_x
            
            
            M = np.c_[ lxx, lyy , np.ones(nstn).T*mesh.vectorNz[-1]]
            N = np.c_[ lxx+a*dl_x, lyy+a*dl_y, np.ones(nstn).T*mesh.vectorNz[-1]]
            
            rx[(ii*nstn):((ii+1)*nstn),:] = np.c_[M,N]
            
        Rx.append(rx)
        
    else:
        print """stype must be either 'pdp', 'dpdp' or 'gradient'. """

        
   
    return Tx, Rx  
Example #4
0
def gen_DCIPsurvey(endl, mesh, stype, a, b, n):
    """
        Load in endpoints and survey specifications to generate Tx, Rx location
        stations.

        Assumes flat topo for now...

        Input:
        :param endl -> input endpoints [x1, y1, z1, x2, y2, z2]
        :object mesh -> SimPEG mesh object
        :switch stype -> "dpdp" (dipole-dipole) | "pdp" (pole-dipole) | 'gradient'
        : param a, n -> pole seperation, number of rx dipoles per tx

        Output:
        :param Tx, Rx -> List objects for each tx location
            Lines: P1x, P1y, P1z, P2x, P2y, P2z

        Created on Wed December 9th, 2015

        @author: dominiquef
        !! Require clean up to deal with DCsurvey
    """

    from SimPEG import np

    def xy_2_r(x1,x2,y1,y2):
        r = np.sqrt( np.sum((x2 - x1)**2 + (y2 - y1)**2) )
        return r

    ## Evenly distribute electrodes and put on surface
    # Mesure survey length and direction
    dl_len = xy_2_r(endl[0,0],endl[1,0],endl[0,1],endl[1,1])

    dl_x = ( endl[1,0] - endl[0,0] ) / dl_len
    dl_y = ( endl[1,1] - endl[0,1] ) / dl_len

    nstn = np.floor( dl_len / a )

    # Compute discrete pole location along line
    stn_x = endl[0,0] + np.array(range(int(nstn)))*dl_x*a
    stn_y = endl[0,1] + np.array(range(int(nstn)))*dl_y*a

    if mesh.dim==2:
        ztop = mesh.vectorNy[-1]
        # Create line of P1 locations
        M = np.c_[stn_x, np.ones(nstn).T*ztop]
        # Create line of P2 locations
        N = np.c_[stn_x+a*dl_x, np.ones(nstn).T*ztop]

    elif mesh.dim==3:
        ztop = mesh.vectorNz[-1]
        # Create line of P1 locations
        M = np.c_[stn_x, stn_y, np.ones(nstn).T*ztop]
        # Create line of P2 locations
        N = np.c_[stn_x+a*dl_x, stn_y+a*dl_y, np.ones(nstn).T*ztop]


    ## Build list of Tx-Rx locations depending on survey type
    # Dipole-dipole: Moving tx with [a] spacing -> [AB a MN1 a MN2 ... a MNn]
    # Pole-dipole: Moving pole on one end -> [A a MN1 a MN2 ... MNn a B]
    SrcList = []


    if stype != 'gradient':

        for ii in range(0, int(nstn)-1):


            if stype == 'dipole-dipole':
                tx = np.c_[M[ii,:],N[ii,:]]
            elif stype == 'pole-dipole':
                tx = np.c_[M[ii,:],M[ii,:]]
            else:
                raise Exception('The stype must be "dipole-dipole" or "pole-dipole"')

            # Rx.append(np.c_[M[ii+1:indx,:],N[ii+1:indx,:]])

            # Current elctrode seperation
            AB = xy_2_r(tx[0,1],endl[1,0],tx[1,1],endl[1,1])

            # Number of receivers to fit
            nstn = np.min([np.floor( (AB - b) / a ) , n])

            # Check if there is enough space, else break the loop
            if nstn <= 0:
                continue

            # Compute discrete pole location along line
            stn_x = N[ii,0] + dl_x*b + np.array(range(int(nstn)))*dl_x*a
            stn_y = N[ii,1] + dl_y*b + np.array(range(int(nstn)))*dl_y*a

            # Create receiver poles

            if mesh.dim==3:
                # Create line of P1 locations
                P1 = np.c_[stn_x, stn_y, np.ones(nstn).T*ztop]
                # Create line of P2 locations
                P2 = np.c_[stn_x+a*dl_x, stn_y+a*dl_y, np.ones(nstn).T*ztop]
                rxClass = DC.Rx.Dipole(P1, P2)

            elif mesh.dim==2:
                # Create line of P1 locations
                P1 = np.c_[stn_x, np.ones(nstn).T*ztop]
                # Create line of P2 locations
                P2 = np.c_[stn_x+a*dl_x, np.ones(nstn).T*ztop]
                rxClass = DC.Rx.Dipole_ky(P1, P2)

            if stype == 'dipole-dipole':
                srcClass = DC.Src.Dipole([rxClass], M[ii,:],N[ii,:])
            elif stype == 'pole-dipole':
                srcClass = DC.Src.Pole([rxClass], M[ii,:])
            SrcList.append(srcClass)

    elif stype == 'gradient':

        # Gradient survey only requires Tx at end of line and creates a square
        # grid of receivers at in the middle at a pre-set minimum distance

        # Get the edge limit of survey area
        min_x = endl[0,0] + dl_x * b
        min_y = endl[0,1] + dl_y * b

        max_x = endl[1,0] - dl_x * b
        max_y = endl[1,1] - dl_y * b

        box_l = np.sqrt( (min_x - max_x)**2 + (min_y - max_y)**2 )
        box_w = box_l/2.

        nstn = np.floor( box_l / a )

        # Compute discrete pole location along line
        stn_x = min_x + np.array(range(int(nstn)))*dl_x*a
        stn_y = min_y + np.array(range(int(nstn)))*dl_y*a

        # Define number of cross lines
        nlin = int(np.floor( box_w / a ))
        lind = list(range(-nlin,nlin+1))

        ngrad = nstn * len(lind)

        rx = np.zeros([ngrad,6])
        for ii in range( len(lind) ):

            # Move line in perpendicular direction by dipole spacing
            lxx = stn_x - lind[ii]*a*dl_y
            lyy = stn_y + lind[ii]*a*dl_x


            M = np.c_[ lxx, lyy , np.ones(nstn).T*ztop]
            N = np.c_[ lxx+a*dl_x, lyy+a*dl_y, np.ones(nstn).T*ztop]
            rx[(ii*nstn):((ii+1)*nstn),:] = np.c_[M,N]

            if mesh.dim==3:
                rxClass = DC.Rx.Dipole(rx[:,:3], rx[:,3:])
            elif mesh.dim==2:
                M = M[:,[0,2]]
                N = N[:,[0,2]]
                rxClass = DC.Rx.Dipole_ky(rx[:,[0,2]], rx[:,[3,5]])
            srcClass = DC.Src.Dipole([rxClass], M[0,:], N[-1,:])
        SrcList.append(srcClass)
    else:
        print("""stype must be either 'pole-dipole', 'dipole-dipole' or 'gradient'. """)


    return SrcList
Example #5
0
ymin = np.min(rxLoc[:, 1])
ymax = np.max(rxLoc[:, 1])

var = np.c_[np.r_[xmin, ymin], np.r_[xmax, ymin], np.r_[xmin, ymax]]
var = np.c_[var.T, np.ones(3) * mesh.vectorCCz[-1]]

# First put a tile on both corners of the mesh
indx = Utils.closestPoints(mesh, var)
endl = np.c_[mesh.gridCC[indx, 0], mesh.gridCC[indx, 1]]

dx = np.median(mesh.hx)

# Add intermediate tiles until the min_Olap is respected
# First in the x-direction
lx = np.floor((max_mcell / mesh.nCz)**0.5)
ntile = 2
Olap = -1

while Olap < min_Olap:

    ntile += 1

    # Set location of SW corners
    #x0 = np.c_[xmin,xmax-lx*dx]

    dx_t = np.round((endl[1, 0] - endl[0, 0]) / ((ntile - 1) * dx))

    x1 = np.r_[endl[0, 0], endl[0, 0] + np.cumsum(
        (np.ones(ntile - 2)) * dx_t * dx), endl[1, 0]]
    x2 = x1 + lx * dx
Example #6
0
def interpFFT(x, y, m):
    """ 
    Load in a 2D grid and resample
    
    OUTPUT:
    m_out


     """

    from SimPEG import np, sp
    import scipy.signal as sn

    # Add padding values by reflection (2**n)
    lenx = np.round(np.log2(2 * len(x)))
    npadx = int(np.floor((2**lenx - len(x)) / 2.))

    #Create hemming taper
    if np.mod(npadx * 2 + len(x), 2) != 0:
        oddx = 1

    else:
        oddx = 0

    tap0 = sn.hamming(npadx * 2)
    tapl = sp.spdiags(tap0[0:npadx], 0, npadx, npadx)
    tapr = sp.spdiags(tap0[npadx:], 0, npadx, npadx + oddx)

    # Mirror the 2d data over the half lenght and apply 0-taper
    mpad = np.hstack(
        [np.fliplr(m[:, 0:npadx]) * tapl, m,
         np.fliplr(m[:, -npadx:]) * tapr])

    # Repeat along the second dimension
    leny = np.round(np.log2(2 * len(y)))
    npady = int(np.floor((2**leny - len(y)) / 2.))

    #Create hemming taper
    if np.mod(npady * 2 + len(y), 2) != 0:
        oddy = 1

    else:
        oddy = 0

    tap0 = sn.hamming(npady * 2)
    tapu = sp.spdiags(tap0[0:npady], 0, npady, npady)
    tapd = sp.spdiags(tap0[npady:], 0, npady + oddy, npady)

    mpad = np.vstack([
        tapu * np.flipud(mpad[0:npady, :]), mpad,
        tapd * np.flipud(mpad[-npady:, :])
    ])

    # Compute FFT
    FFTm = np.fft.fft2(mpad)

    # Do an FFT shift
    FFTshift = np.fft.fftshift(FFTm)

    # Pad high frequencies with zeros to increase the sampling rate
    py = int(FFTm.shape[0] / 2)
    px = int(FFTm.shape[1] / 2)

    FFTshift = np.hstack([
        np.zeros((FFTshift.shape[0], px)), FFTshift,
        np.zeros((FFTshift.shape[0], px))
    ])
    FFTshift = np.vstack([
        np.zeros((py, FFTshift.shape[1])), FFTshift,
        np.zeros((py, FFTshift.shape[1]))
    ])

    # Inverse shift
    FFTm = np.fft.ifftshift(FFTshift)

    # Compute inverse FFT
    IFFTm = np.fft.ifft2(FFTm) * FFTm.size / mpad.size

    m_out = np.real(IFFTm)
    # Extract core
    #m_out = np.real(IFFTm[npady*2:-(npady*2+oddy+1),npadx*2:-(npadx*2+oddx+1)])

    m_out = m_out[npady * 2:-(npady + oddy) * 2, npadx * 2:-(npadx + oddx) * 2]

    if np.mod(m.shape[0], 2) != 0:
        m_out = m_out[:-1, :]

    if np.mod(m.shape[1], 2) != 0:
        m_out = m_out[:, :-1]

    return m_out