Exemple #1
0
    def _evalCross(self, m):
        if self.crossgrad == False:
            return 0.0
        elif self.crossgrad == True:
            M = (self.mapping * m).reshape((self.regmesh.nC, self.nModels), order="F")

            ax = self.regmesh.aveFx2CC * self.regmesh.wx[0] * M[:, 0]
            ay = self.regmesh.aveFy2CC * self.regmesh.wy[0] * M[:, 0]
            az = self.regmesh.aveFz2CC * self.regmesh.wz[0] * M[:, 0]
            bx = self.regmesh.aveFx2CC * self.regmesh.wx[1] * M[:, 1]
            by = self.regmesh.aveFy2CC * self.regmesh.wy[1] * M[:, 1]
            bz = self.regmesh.aveFz2CC * self.regmesh.wz[1] * M[:, 1]
            # ab
            out_ab = cross([ax, ay, az], [bx, by, bz])
            r = np.r_[out_ab[0], out_ab[1], out_ab[2]] * np.sqrt(self.betacross)

            if self.nModels == 3:
                cx = self.regmesh.aveFx2CC * self.regmesh.wx[1] * M[:, 1]
                cy = self.regmesh.aveFy2CC * self.regmesh.wy[1] * M[:, 1]
                cz = self.regmesh.aveFz2CC * self.regmesh.wz[1] * M[:, 1]
                # ac
                out_ac = cross([ax, ay, az], [cx, cy, cz])
                # bc
                out_bc = cross([bx, by, bz], [cx, cy, cz])
                r = np.r_[r, np.hstack(out_ac) * np.sqrt(self.betacross), np.hstack(out_bc) * np.sqrt(self.betacross)]

            return 0.5 * r.dot(r)
Exemple #2
0
def readUBC_DC2DLoc(fileName):

    from SimPEG import np
    """
        Read UBC GIF 2D observation file and generate arrays for tx-rx location

        Input:
        :param fileName, path to the UBC GIF 2D model file

        Output:
        :param rx, tx
        :return
        
        Created on Thu Nov 12 13:14:10 2015

        @author: dominiquef

    """
    
    # Open fileand skip header... assume that we know the mesh already
#==============================================================================
#     fopen = open(fileName,'r')
#     lines = fopen.readlines()
#     fopen.close()
#==============================================================================

    # Load file
    obsfile = np.genfromtxt(fileName,delimiter=' \n',dtype=np.str,comments='!')
    
    # Check first line and figure out if 2D or 3D file format
    line = np.array(obsfile[0].split(),dtype=float)   
    
    tx_A  = []
    tx_B  = []
    rx_M  = []
    rx_N  = []
    d   = []
    wd  = []
    
    for ii in range(obsfile.shape[0]):
        
        # If len==3, then simple format where tx-rx is listed on each line
        if len(line) == 4:
        
            temp = np.fromstring(obsfile[ii], dtype=float,sep=' ')
            tx_A = np.hstack((tx_A,temp[0]))
            tx_B = np.hstack((tx_B,temp[1]))
            rx_M = np.hstack((rx_M,temp[2]))
            rx_N = np.hstack((rx_N,temp[3]))
            
        
    rx = np.transpose(np.array((rx_M,rx_N)))    
    tx = np.transpose(np.array((tx_A,tx_B)))
    
    return tx, rx, d, wd
Exemple #3
0
    def toRecArray(self,returnType='RealImag'):
        '''
        Function that returns a numpy.recarray for a SimpegMT impedance data object.

        :param str returnType: Switches between returning a rec array where the impedance is split to real and imaginary ('RealImag') or is a complex ('Complex')

        '''

        # Define the record fields
        dtRI = [('freq',float),('x',float),('y',float),('z',float),('zxxr',float),('zxxi',float),('zxyr',float),('zxyi',float),
        ('zyxr',float),('zyxi',float),('zyyr',float),('zyyi',float),('tzxr',float),('tzxi',float),('tzyr',float),('tzyi',float)]
        dtCP = [('freq',float),('x',float),('y',float),('z',float),('zxx',complex),('zxy',complex),('zyx',complex),('zyy',complex),('tzx',complex),('tzy',complex)]
        impList = ['zxxr','zxxi','zxyr','zxyi','zyxr','zyxi','zyyr','zyyi']
        for src in self.survey.srcList:
            # Temp array for all the receivers of the source.
            # Note: needs to be written more generally, using diffterent rxTypes and not all the data at the locaitons
            # Assume the same locs for all RX
            locs = src.rxList[0].locs
            if locs.shape[1] == 1:
                locs = np.hstack((np.array([[0.0,0.0]]),locs))
            elif locs.shape[1] == 2:
                locs = np.hstack((np.array([[0.0]]),locs))
            tArrRec = np.concatenate((src.freq*np.ones((locs.shape[0],1)),locs,np.nan*np.ones((locs.shape[0],12))),axis=1).view(dtRI)
            # np.array([(src.freq,rx.locs[0,0],rx.locs[0,1],rx.locs[0,2],np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ) for rx in src.rxList],dtype=dtRI)
            # Get the type and the value for the DataMT object as a list
            typeList = [[rx.rxType.replace('z1d','zyx'),self[src,rx]] for rx in src.rxList]
            # Insert the values to the temp array
            for nr,(key,val) in enumerate(typeList):
                tArrRec[key] = mkvc(val,2)
            # Masked array
            mArrRec = np.ma.MaskedArray(rec2ndarr(tArrRec),mask=np.isnan(rec2ndarr(tArrRec))).view(dtype=tArrRec.dtype)
            # Unique freq and loc of the masked array
            uniFLmarr = np.unique(mArrRec[['freq','x','y','z']]).copy()

            try:
                outTemp = recFunc.stack_arrays((outTemp,mArrRec))
                #outTemp = np.concatenate((outTemp,dataBlock),axis=0)
            except NameError as e:
                outTemp = mArrRec

            if 'RealImag' in returnType:
                outArr = outTemp
            elif 'Complex' in returnType:
                # Add the real and imaginary to a complex number
                outArr = np.empty(outTemp.shape,dtype=dtCP)
                for comp in ['freq','x','y','z']:
                    outArr[comp] = outTemp[comp].copy()
                for comp in ['zxx','zxy','zyx','zyy','tzx','tzy']:
                    outArr[comp] = outTemp[comp+'r'].copy() + 1j*outTemp[comp+'i'].copy()
            else:
                raise NotImplementedError('{:s} is not implemented, as to be RealImag or Complex.')

        # Return
        return outArr
Exemple #4
0
 def S_eDeriv_m(self, problem, v, adjoint=False):
     """
     Get the derivative of S_e wrt to sigma (m)
     """
     # Need to deal with
     if problem.mesh.dim == 1:
         # Need to use the faceInnerProduct
         MsigmaDeriv = (
             problem.mesh.getFaceInnerProductDeriv(problem.curModel.sigma)(self.ePrimary(problem)[:, 1])
             * problem.curModel.sigmaDeriv
         )
         # MsigmaDeriv = ( MsigmaDeriv * MsigmaDeriv.T)**2
     if problem.mesh.dim == 2:
         pass
     if problem.mesh.dim == 3:
         # Need to take the derivative of both u_px and u_py
         ePri = self.ePrimary(problem)
         # MsigmaDeriv = problem.MeSigmaDeriv(ePri[:,0]) + problem.MeSigmaDeriv(ePri[:,1])
         # MsigmaDeriv = problem.MeSigmaDeriv(np.sum(ePri,axis=1))
         if adjoint:
             return sp.hstack((problem.MeSigmaDeriv(ePri[:, 0]).T, problem.MeSigmaDeriv(ePri[:, 1]).T)) * v
         else:
             return np.hstack(
                 (mkvc(problem.MeSigmaDeriv(ePri[:, 0]) * v, 2), mkvc(problem.MeSigmaDeriv(ePri[:, 1]) * v, 2))
             )
     if adjoint:
         #
         return MsigmaDeriv.T * v
     else:
         # v should be nC size
         return MsigmaDeriv * v
Exemple #5
0
 def Wsmall(self):
     """Regularization matrix Wsmall"""
     if getattr(self, "_Wsmall", None) is None:
         vecs = []
         for imodel in range(self.nModels):
             vecs.append((self.regmesh.vol * self.alpha_s * self.wght * self.ratios[imodel]) ** 0.5)
         self._Wsmall = Utils.sdiag(np.hstack(vecs))
     return self._Wsmall
Exemple #6
0
def run(plotIt=True, nFreq=1):
    """
        MT: 3D: Forward
        ===============

        Forward model 3D MT data.

    """

    # Make a mesh
    M = simpeg.Mesh.TensorMesh([[(100,5,-1.5),(100.,10),(100,5,1.5)],[(100,5,-1.5),(100.,10),(100,5,1.5)],[(100,5,1.6),(100.,10),(100,3,2)]], x0=['C','C',-3529.5360])
    # Setup the model
    conds = [1e-2,1]
    sig = simpeg.Utils.ModelBuilder.defineBlock(M.gridCC,[-1000,-1000,-400],[1000,1000,-200],conds)
    sig[M.gridCC[:,2]>0] = 1e-8
    sig[M.gridCC[:,2]<-600] = 1e-1
    sigBG = np.zeros(M.nC) + conds[0]
    sigBG[M.gridCC[:,2]>0] = 1e-8

    ## Setup the the survey object
    # Receiver locations
    rx_x, rx_y = np.meshgrid(np.arange(-500,501,50),np.arange(-500,501,50))
    rx_loc = np.hstack((simpeg.Utils.mkvc(rx_x,2),simpeg.Utils.mkvc(rx_y,2),np.zeros((np.prod(rx_x.shape),1))))
    # Make a receiver list
    rxList = []
    for loc in rx_loc:
        # NOTE: loc has to be a (1,3) np.ndarray otherwise errors accure
        for rx_orientation in ['xx','xy','yx','yy']:
            rxList.append(NSEM.Rx.Point_impedance3D(simpeg.mkvc(loc,2).T,rx_orientation, 'real'))
            rxList.append(NSEM.Rx.Point_impedance3D(simpeg.mkvc(loc,2).T,rx_orientation, 'imag'))
        for rx_orientation in ['zx','zy']:
            rxList.append(NSEM.Rx.Point_tipper3D(simpeg.mkvc(loc,2).T,rx_orientation, 'real'))
            rxList.append(NSEM.Rx.Point_tipper3D(simpeg.mkvc(loc,2).T,rx_orientation, 'imag'))
    # Source list
    srcList =[]
    for freq in np.logspace(3,-3,nFreq):
        srcList.append(NSEM.Src.Planewave_xy_1Dprimary(rxList,freq))
    # Survey MT
    survey = NSEM.Survey(srcList)

    ## Setup the problem object
    problem = NSEM.Problem3D_ePrimSec(M, sigmaPrimary=sigBG)

    problem.pair(survey)
    problem.Solver = Solver

    # Calculate the data
    fields = problem.fields(sig)
    dataVec = survey.eval(fields)

    # Make the data
    mtData = NSEM.Data(survey,dataVec)

    # Add plots
    if plotIt:
        pass
Exemple #7
0
    def getADeriv_m(self, freq, u, v, adjoint=False):
        """
        Calculate the derivative of A wrt m.

        """

        # This considers both polarizations and returns a nE,2 matrix for each polarization
        if adjoint:
            dMe_dsigV = sp.hstack(( self.MeSigmaDeriv( u['e_pxSolution'] ).T, self.MeSigmaDeriv(u['e_pySolution'] ).T ))*v
        else:
            # Need a nE,2 matrix to be returned
            dMe_dsigV = np.hstack(( mkvc(self.MeSigmaDeriv( u['e_pxSolution'] )*v,2), mkvc( self.MeSigmaDeriv(u['e_pySolution'] )*v,2) ))
        return 1j * omega(freq) * dMe_dsigV
Exemple #8
0
    def fromRecArray(cls, recArray, srcType='primary'):
        """
        Class method that reads in a numpy record array to MTdata object.

        Only imports the impedance data.

        """
        if srcType == 'primary':
            src = simpegMT.SurveyMT.srcMT_polxy_1Dprimary
        elif srcType == 'total':
            src = sdsimpegMT.SurveyMT.srcMT_polxy_1DhomotD
        else:
            raise NotImplementedError(
                '{:s} is not a valid source type for MTdata')

        # Find all the frequencies in recArray
        uniFreq = np.unique(recArray['freq'])
        srcList = []
        dataList = []
        for freq in uniFreq:
            # Initiate rxList
            rxList = []
            # Find that data for freq
            dFreq = recArray[recArray['freq'] == freq].copy()
            # Find the impedance rxTypes in the recArray.
            rxTypes = [
                comp for comp in recArray.dtype.names
                if (len(comp) == 4 or len(comp) == 3) and 'z' in comp
            ]
            for rxType in rxTypes:
                # Find index of not nan values in rxType
                notNaNind = ~np.isnan(dFreq[rxType])
                if np.any(
                        notNaNind):  # Make sure that there is any data to add.
                    locs = rec2ndarr(dFreq[['x', 'y', 'z']][notNaNind].copy())
                    if dFreq[rxType].dtype.name in 'complex128':
                        rxList.append(
                            simpegMT.SurveyMT.RxMT(locs, rxType + 'r'))
                        dataList.append(dFreq[rxType][notNaNind].real.copy())
                        rxList.append(
                            simpegMT.SurveyMT.RxMT(locs, rxType + 'i'))
                        dataList.append(dFreq[rxType][notNaNind].imag.copy())
                    else:
                        rxList.append(simpegMT.SurveyMT.RxMT(locs, rxType))
                        dataList.append(dFreq[rxType][notNaNind].copy())
            srcList.append(src(rxList, freq))

        # Make a survey
        survey = simpegMT.SurveyMT.SurveyMT(srcList)
        dataVec = np.hstack(dataList)
        return cls(survey, dataVec)
Exemple #9
0
 def unpackdx(fid,nrows):
     for ii in range(nrows):
         
         line = fid.readline()
         var = np.array(line.split(),dtype=float)
         
         if ii==0:
             x0= var[0]
             xvec = np.ones(int(var[2])) * (var[1] - var[0]) / int(var[2])
             xend = var[1]            
             
         else:
             xvec = np.hstack((xvec,np.ones(int(var[1])) * (var[0] - xend) / int(var[1])))
             xend = var[0] 
             
     return x0, xvec
Exemple #10
0
    def getADeriv_m(self, freq, u, v, adjoint=False):
        """
        Calculate the derivative of A wrt m.

        """

        # This considers both polarizations and returns a nE,2 matrix for each polarization
        if adjoint:
            dMe_dsigV = sp.hstack((self.MeSigmaDeriv(u['e_pxSolution']).T,
                                   self.MeSigmaDeriv(u['e_pySolution']).T)) * v
        else:
            # Need a nE,2 matrix to be returned
            dMe_dsigV = np.hstack(
                (mkvc(self.MeSigmaDeriv(u['e_pxSolution']) * v,
                      2), mkvc(self.MeSigmaDeriv(u['e_pySolution']) * v, 2)))
        return 1j * omega(freq) * dMe_dsigV
Exemple #11
0
    def unpackdx(fid,nrows):
        for ii in range(nrows):

            line = fid.readline()
            var = np.array(line.split(),dtype=float)

            if ii==0:
                x0= var[0]
                xvec = np.ones(int(var[2])) * (var[1] - var[0]) / int(var[2])
                xend = var[1]

            else:
                xvec = np.hstack((xvec,np.ones(int(var[1])) * (var[0] - xend) / int(var[1])))
                xend = var[0]

        return x0, xvec
Exemple #12
0
    def fromRecArray(cls, recArray, srcType='primary'):
        """
        Class method that reads in a numpy record array to MTdata object.

        Only imports the impedance data.

        """
        if srcType=='primary':
            src = SrcMT.polxy_1Dprimary
        elif srcType=='total':
            src = SrcMT.polxy_1DhomotD
        else:
            raise NotImplementedError('{:s} is not a valid source type for MTdata')

        # Find all the frequencies in recArray
        uniFreq = np.unique(recArray['freq'])
        srcList = []
        dataList = []
        for freq in uniFreq:
            # Initiate rxList
            rxList = []
            # Find that data for freq
            dFreq = recArray[recArray['freq'] == freq].copy()
            # Find the impedance rxTypes in the recArray.
            rxTypes = [ comp for comp in recArray.dtype.names if (len(comp)==4 or len(comp)==3) and 'z' in comp]
            for rxType in rxTypes:
                # Find index of not nan values in rxType
                notNaNind = ~np.isnan(dFreq[rxType])
                if np.any(notNaNind): # Make sure that there is any data to add.
                    locs = rec2ndarr(dFreq[['x','y','z']][notNaNind].copy())
                    if dFreq[rxType].dtype.name in 'complex128':
                        rxList.append(Rx(locs,rxType+'r'))
                        dataList.append(dFreq[rxType][notNaNind].real.copy())
                        rxList.append(Rx(locs,rxType+'i'))
                        dataList.append(dFreq[rxType][notNaNind].imag.copy())
                    else:
                        rxList.append(Rx(locs,rxType))
                        dataList.append(dFreq[rxType][notNaNind].copy())
            srcList.append(src(rxList,freq))

        # Make a survey
        survey = Survey(srcList)
        dataVec = np.hstack(dataList)
        return cls(survey,dataVec)
Exemple #13
0
def run(plotIt=True):
    """
        Maps: Parametrized Block in a Layer
        ===================================

        Parametrized description of a block confined to a layer in a
        wholespace. The mapping can be applied in 2D or 3D. Here we show a 2D
        example.

        The model is given by

        .. code::

            m = np.r_[
               'value of the background',
               'value in the layer',
               'value in the block',
               'center of the layer (depth)',
               'thickness of the layer',
               'x-center of block',
               'width of the block'
            ]

    """

    mesh = Mesh.TensorMesh([50, 50], x0='CC')  # 2D Tensor Mesh
    mapping = Maps.ParametrizedBlockInLayer(mesh)  # mapping

    m = np.hstack(np.r_[1.,  # value of the background
                        2.,  # value in the layer
                        3.,  # value in the block
                        -0.1,  # center of the layer (depth)
                        0.2,  # thickness of the layer
                        0.3,  # x-center of block
                        0.2  # width of the block
                        ])

    # apply the mapping to define the physical property on the mesh
    rho = mapping * m

    if plotIt is True:
        fig, ax = plt.subplots(1, 1, figsize=(4, 6))
        mesh.plotImage(rho, ax=ax)
Exemple #14
0
    def getADeriv_m(self, freq, u, v, adjoint=False):

        # Nee to account for both the polarizations
        # dMe_dsig = (self.MeSigmaDeriv( u['e_pxSolution'] ) + self.MeSigmaDeriv( u['e_pySolution'] ))
        # dMe_dsig = (self.MeSigmaDeriv( u['e_pxSolution'] +  u['e_pySolution'] ))

        # # dMe_dsig = self.MeSigmaDeriv( u )
        # if adjoint:
        #     return 1j * omega(freq) * ( dMe_dsig.T * v ) # As in simpegEM

        # return 1j * omega(freq) * ( dMe_dsig * v ) # As in simpegEM

        # This considers both polarizations and returns a nE,2 matrix for each polarization
        if adjoint:
            dMe_dsigV = sp.hstack((self.MeSigmaDeriv(u['e_pxSolution']).T,
                                   self.MeSigmaDeriv(u['e_pySolution']).T)) * v
        else:
            # Need a nE,2 matrix to be returned
            dMe_dsigV = np.hstack(
                (mkvc(self.MeSigmaDeriv(u['e_pxSolution']) * v,
                      2), mkvc(self.MeSigmaDeriv(u['e_pySolution']) * v, 2)))
        return 1j * omega(freq) * dMe_dsigV
Exemple #15
0
    def Jvec(self, m, v, f=None):
        """
        Sensitivity times a vector.

        :param numpy.array m: inversion model (nP,)
        :param numpy.array v: vector which we take sensitivity product with (nP,)
        :param SimPEG.EM.FDEM.FieldsFDEM.FieldsFDEM u: fields object
        :rtype: numpy.array
        :return: Jv (ndata,)
        """

        if f is None:
           f = self.fields(m)

        self.curModel = m

        # Jv = self.dataPair(self.survey)
        Jv = []

        for freq in self.survey.freqs:
            A = self.getA(freq)
            Ainv = self.Solver(A, **self.solverOpts) # create the concept of Ainv (actually a solve)

            for src in self.survey.getSrcByFreq(freq):
                u_src = f[src, self._solutionType]
                dA_dm_v = self.getADeriv(freq, u_src, v)
                dRHS_dm_v = self.getRHSDeriv(freq, src, v)
                du_dm_v = Ainv * ( - dA_dm_v + dRHS_dm_v )

                for rx in src.rxList:
                    df_dmFun = getattr(f, '_{0}Deriv'.format(rx.projField), None)
                    df_dm_v = df_dmFun(src, du_dm_v, v, adjoint=False)
                    # Jv[src, rx] = rx.evalDeriv(src, self.mesh, f, df_dm_v)
                    Jv.append(rx.evalDeriv(src, self.mesh, f, df_dm_v))
            Ainv.clean()
        # return Utils.mkvc(Jv)
        return np.hstack(Jv)
Exemple #16
0
def run(plotIt=True):
    """
        Maps: Parametrized Layer
        ========================

        Build a model of a parametrized layer in a wholespace. If you want to
        build a model of a parametrized layer in a halfspace, also use
        Maps.InjectActiveCell.

        The model is

        .. code::

            m = [
                'background physical property value',
                'layer physical property value',
                'layer center',
                'layer thickness'
            ]

    """

    mesh = Mesh.TensorMesh([50, 50], x0='CC')  # 2D tensor mesh
    mapping = Maps.ParametrizedLayer(mesh)  # parametrized layer in wholespace

    # model
    m = np.hstack(np.r_[1.,  # background value
                        2.,  # layer value
                        -0.1,  # layer center
                        0.2  # layer thickness
                        ])
    rho = mapping * m  # apply the mapping

    if plotIt is True:
        fig, ax = plt.subplots(1, 1, figsize=(4, 6))
        mesh.plotImage(rho, ax=ax)
Exemple #17
0
    def evalDeriv(self, src, mesh, f, v, adjoint=False):
        """
        The derivative of the projection wrt u

        :param MTsrc src: MT source
        :param TensorMesh mesh: Mesh defining the topology of the problem
        :param MTfields f: MT fields object of the source
        :param numpy.ndarray v: Random vector of size
        """

        real_or_imag = self.projComp

        if not adjoint:
            if self.projType is 'Z1D':
                Pex = mesh.getInterpolationMat(self.locs[:,-1],'Fx')
                Pbx = mesh.getInterpolationMat(self.locs[:,-1],'Ex')
                # ex = Pex*mkvc(f[src,'e_1d'],2)
                # bx = Pbx*mkvc(f[src,'b_1d'],2)/mu_0
                dP_de = -mkvc(Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))*(Pex*v),2)
                dP_db = mkvc( Utils.sdiag(Pex*mkvc(f[src,'e_1d'],2))*(Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)).T*Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)))*(Pbx*f._bDeriv_u(src,v)/mu_0),2)
                PDeriv_complex = np.sum(np.hstack((dP_de,dP_db)),1)
            elif self.projType is 'Z2D':
                raise NotImplementedError('Has not been implement for 2D impedance tensor')
            elif self.projType is 'Z3D':
                if self.locs.ndim == 3:
                    eFLocs = self.locs[:,:,0]
                    bFLocs = self.locs[:,:,1]
                else:
                    eFLocs = self.locs
                    bFLocs = self.locs
                # Get the projection
                Pex = mesh.getInterpolationMat(eFLocs,'Ex')
                Pey = mesh.getInterpolationMat(eFLocs,'Ey')
                Pbx = mesh.getInterpolationMat(bFLocs,'Fx')
                Pby = mesh.getInterpolationMat(bFLocs,'Fy')
                # Get the fields at location
                # px: x-polaration and py: y-polaration.
                ex_px = Pex*f[src,'e_px']
                ey_px = Pey*f[src,'e_px']
                ex_py = Pex*f[src,'e_py']
                ey_py = Pey*f[src,'e_py']
                hx_px = Pbx*f[src,'b_px']/mu_0
                hy_px = Pby*f[src,'b_px']/mu_0
                hx_py = Pbx*f[src,'b_py']/mu_0
                hy_py = Pby*f[src,'b_py']/mu_0
                # Derivatives as lambda functions
                # The size of the diratives should be nD,nU
                ex_px_u = lambda vec: Pex*f._e_pxDeriv_u(src,vec)
                ey_px_u = lambda vec: Pey*f._e_pxDeriv_u(src,vec)
                ex_py_u = lambda vec: Pex*f._e_pyDeriv_u(src,vec)
                ey_py_u = lambda vec: Pey*f._e_pyDeriv_u(src,vec)
                # NOTE: Think b_p?Deriv_u should return a 2*nF size matrix
                hx_px_u = lambda vec: Pbx*f._b_pxDeriv_u(src,vec)/mu_0
                hy_px_u = lambda vec: Pby*f._b_pxDeriv_u(src,vec)/mu_0
                hx_py_u = lambda vec: Pbx*f._b_pyDeriv_u(src,vec)/mu_0
                hy_py_u = lambda vec: Pby*f._b_pyDeriv_u(src,vec)/mu_0
                # Update the input vector
                sDiag = lambda t: Utils.sdiag(mkvc(t,2))
                # Define the components of the derivative
                Hd = sDiag(1./(sDiag(hx_px)*hy_py - sDiag(hx_py)*hy_px))
                Hd_uV = sDiag(hy_py)*hx_px_u(v) + sDiag(hx_px)*hy_py_u(v) - sDiag(hx_py)*hy_px_u(v) - sDiag(hy_px)*hx_py_u(v)
                # Calculate components
                if 'zxx' in self.rxType:
                    Zij = sDiag(Hd*( sDiag(ex_px)*hy_py - sDiag(ex_py)*hy_px ))
                    ZijN_uV =  sDiag(hy_py)*ex_px_u(v) + sDiag(ex_px)*hy_py_u(v) - sDiag(ex_py)*hy_px_u(v) - sDiag(hy_px)*ex_py_u(v)
                elif 'zxy' in self.rxType:
                    Zij = sDiag(Hd*(-sDiag(ex_px)*hx_py + sDiag(ex_py)*hx_px ))
                    ZijN_uV = -sDiag(hx_py)*ex_px_u(v) - sDiag(ex_px)*hx_py_u(v) + sDiag(ex_py)*hx_px_u(v) + sDiag(hx_px)*ex_py_u(v)
                elif 'zyx' in self.rxType:
                    Zij = sDiag(Hd*( sDiag(ey_px)*hy_py - sDiag(ey_py)*hy_px ))
                    ZijN_uV =  sDiag(hy_py)*ey_px_u(v) + sDiag(ey_px)*hy_py_u(v) - sDiag(ey_py)*hy_px_u(v) - sDiag(hy_px)*ey_py_u(v)
                elif 'zyy' in self.rxType:
                    Zij = sDiag(Hd*(-sDiag(ey_px)*hx_py + sDiag(ey_py)*hx_px ))
                    ZijN_uV = -sDiag(hx_py)*ey_px_u(v) - sDiag(ey_px)*hx_py_u(v) + sDiag(ey_py)*hx_px_u(v) + sDiag(hx_px)*ey_py_u(v)

                # Calculate the complex derivative
                PDeriv_complex = Hd * (ZijN_uV - Zij * Hd_uV )
            elif self.projType is 'T3D':
                if self.locs.ndim == 3:
                    eFLocs = self.locs[:,:,0]
                    bFLocs = self.locs[:,:,1]
                else:
                    eFLocs = self.locs
                    bFLocs = self.locs
                # Get the projection
                Pbx = mesh.getInterpolationMat(bFLocs,'Fx')
                Pby = mesh.getInterpolationMat(bFLocs,'Fy')
                Pbz = mesh.getInterpolationMat(bFLocs,'Fz')

                # Get the fields at location
                # px: x-polaration and py: y-polaration.
                bx_px = Pbx*f[src,'b_px']
                by_px = Pby*f[src,'b_px']
                bz_px = Pbz*f[src,'b_px']
                bx_py = Pbx*f[src,'b_py']
                by_py = Pby*f[src,'b_py']
                bz_py = Pbz*f[src,'b_py']
                # Derivatives as lambda functions
                # NOTE: Think b_p?Deriv_u should return a 2*nF size matrix
                bx_px_u = lambda vec: Pbx*f._b_pxDeriv_u(src,vec)
                by_px_u = lambda vec: Pby*f._b_pxDeriv_u(src,vec)
                bz_px_u = lambda vec: Pbz*f._b_pxDeriv_u(src,vec)
                bx_py_u = lambda vec: Pbx*f._b_pyDeriv_u(src,vec)
                by_py_u = lambda vec: Pby*f._b_pyDeriv_u(src,vec)
                bz_py_u = lambda vec: Pbz*f._b_pyDeriv_u(src,vec)
                # Update the input vector
                sDiag = lambda t: Utils.sdiag(mkvc(t,2))
                # Define the components of the derivative
                Hd = sDiag(1./(sDiag(bx_px)*by_py - sDiag(bx_py)*by_px))
                Hd_uV = sDiag(by_py)*bx_px_u(v) + sDiag(bx_px)*by_py_u(v) - sDiag(bx_py)*by_px_u(v) - sDiag(by_px)*bx_py_u(v)
                if 'tzx' in self.rxType:
                    Tij = sDiag(Hd*( - sDiag(by_px)*bz_py + sDiag(by_py)*bz_px ))
                    TijN_uV = -sDiag(by_px)*bz_py_u(v) - sDiag(bz_py)*by_px_u(v) + sDiag(by_py)*bz_px_u(v) + sDiag(bz_px)*by_py_u(v)
                elif 'tzy' in self.rxType:
                    Tij = sDiag(Hd*( sDiag(bx_px)*bz_py - sDiag(bx_py)*bz_px ))
                    TijN_uV =  sDiag(bz_py)*bx_px_u(v) + sDiag(bx_px)*bz_py_u(v) - sDiag(bx_py)*bz_px_u(v) - sDiag(bz_px)*bx_py_u(v)
                # Calculate the complex derivative
                PDeriv_complex = Hd * (TijN_uV - Tij * Hd_uV )

            # Extract the real number for the real/imag components.
            Pv = np.array(getattr(PDeriv_complex, real_or_imag))
        elif adjoint:
            # Note: The v vector is real and the return should be complex
            if self.projType is 'Z1D':
                Pex = mesh.getInterpolationMat(self.locs[:,-1],'Fx')
                Pbx = mesh.getInterpolationMat(self.locs[:,-1],'Ex')
                # ex = Pex*mkvc(f[src,'e_1d'],2)
                # bx = Pbx*mkvc(f[src,'b_1d'],2)/mu_0
                dP_deTv = -mkvc(Pex.T*Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0)).T*v,2)
                db_duv = Pbx.T/mu_0*Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))*(Utils.sdiag(1./(Pbx*mkvc(f[src,'b_1d'],2)/mu_0))).T*Utils.sdiag(Pex*mkvc(f[src,'e_1d'],2)).T*v
                dP_dbTv = mkvc(f._bDeriv_u(src,db_duv,adjoint=True),2)
                PDeriv_real = np.sum(np.hstack((dP_deTv,dP_dbTv)),1)
            elif self.projType is 'Z2D':
                raise NotImplementedError('Has not be implement for 2D impedance tensor')
            elif self.projType is 'Z3D':
                if self.locs.ndim == 3:
                    eFLocs = self.locs[:,:,0]
                    bFLocs = self.locs[:,:,1]
                else:
                    eFLocs = self.locs
                    bFLocs = self.locs
                # Get the projection
                Pex = mesh.getInterpolationMat(eFLocs,'Ex')
                Pey = mesh.getInterpolationMat(eFLocs,'Ey')
                Pbx = mesh.getInterpolationMat(bFLocs,'Fx')
                Pby = mesh.getInterpolationMat(bFLocs,'Fy')
                # Get the fields at location
                # px: x-polaration and py: y-polaration.
                aex_px = mkvc(mkvc(f[src,'e_px'],2).T*Pex.T)
                aey_px = mkvc(mkvc(f[src,'e_px'],2).T*Pey.T)
                aex_py = mkvc(mkvc(f[src,'e_py'],2).T*Pex.T)
                aey_py = mkvc(mkvc(f[src,'e_py'],2).T*Pey.T)
                ahx_px = mkvc(mkvc(f[src,'b_px'],2).T/mu_0*Pbx.T)
                ahy_px = mkvc(mkvc(f[src,'b_px'],2).T/mu_0*Pby.T)
                ahx_py = mkvc(mkvc(f[src,'b_py'],2).T/mu_0*Pbx.T)
                ahy_py = mkvc(mkvc(f[src,'b_py'],2).T/mu_0*Pby.T)
                # Derivatives as lambda functions
                aex_px_u = lambda vec: f._e_pxDeriv_u(src,Pex.T*vec,adjoint=True)
                aey_px_u = lambda vec: f._e_pxDeriv_u(src,Pey.T*vec,adjoint=True)
                aex_py_u = lambda vec: f._e_pyDeriv_u(src,Pex.T*vec,adjoint=True)
                aey_py_u = lambda vec: f._e_pyDeriv_u(src,Pey.T*vec,adjoint=True)
                ahx_px_u = lambda vec: f._b_pxDeriv_u(src,Pbx.T*vec,adjoint=True)/mu_0
                ahy_px_u = lambda vec: f._b_pxDeriv_u(src,Pby.T*vec,adjoint=True)/mu_0
                ahx_py_u = lambda vec: f._b_pyDeriv_u(src,Pbx.T*vec,adjoint=True)/mu_0
                ahy_py_u = lambda vec: f._b_pyDeriv_u(src,Pby.T*vec,adjoint=True)/mu_0

                # Update the input vector
                # Define shortcuts
                sDiag = lambda t: Utils.sdiag(mkvc(t,2))
                sVec = lambda t: Utils.sp.csr_matrix(mkvc(t,2))
                # Define the components of the derivative
                aHd = sDiag(1./(sDiag(ahx_px)*ahy_py - sDiag(ahx_py)*ahy_px))
                aHd_uV = lambda x: ahx_px_u(sDiag(ahy_py)*x) + ahx_px_u(sDiag(ahy_py)*x) - ahy_px_u(sDiag(ahx_py)*x) - ahx_py_u(sDiag(ahy_px)*x)
                # Need to fix this to reflect the adjoint
                if 'zxx' in self.rxType:
                    Zij = sDiag(aHd*( sDiag(ahy_py)*aex_px - sDiag(ahy_px)*aex_py))
                    ZijN_uV = lambda x: aex_px_u(sDiag(ahy_py)*x) + ahy_py_u(sDiag(aex_px)*x) - ahy_px_u(sDiag(aex_py)*x) - aex_py_u(sDiag(ahy_px)*x)
                elif 'zxy' in self.rxType:
                    Zij = sDiag(aHd*(-sDiag(ahx_py)*aex_px + sDiag(ahx_px)*aex_py))
                    ZijN_uV = lambda x:-aex_px_u(sDiag(ahx_py)*x) - ahx_py_u(sDiag(aex_px)*x) + ahx_px_u(sDiag(aex_py)*x) + aex_py_u(sDiag(ahx_px)*x)
                elif 'zyx' in self.rxType:
                    Zij = sDiag(aHd*( sDiag(ahy_py)*aey_px - sDiag(ahy_px)*aey_py))
                    ZijN_uV = lambda x: aey_px_u(sDiag(ahy_py)*x) + ahy_py_u(sDiag(aey_px)*x) - ahy_px_u(sDiag(aey_py)*x) - aey_py_u(sDiag(ahy_px)*x)
                elif 'zyy' in self.rxType:
                    Zij = sDiag(aHd*(-sDiag(ahx_py)*aey_px + sDiag(ahx_px)*aey_py))
                    ZijN_uV = lambda x:-aey_px_u(sDiag(ahx_py)*x) - ahx_py_u(sDiag(aey_px)*x) + ahx_px_u(sDiag(aey_py)*x) + aey_py_u(sDiag(ahx_px)*x)

                # Calculate the complex derivative
                PDeriv_real = ZijN_uV(aHd*v) - aHd_uV(Zij.T*aHd*v)#
                # NOTE: Need to reshape the output to go from 2*nU array to a (nU,2) matrix for each polarization
                # PDeriv_real = np.hstack((mkvc(PDeriv_real[:len(PDeriv_real)/2],2),mkvc(PDeriv_real[len(PDeriv_real)/2::],2)))
                PDeriv_real = PDeriv_real.reshape((2,mesh.nE)).T

            elif self.projType is 'T3D':
                if self.locs.ndim == 3:
                    bFLocs = self.locs[:,:,1]
                else:
                    bFLocs = self.locs
                # Get the projection
                Pbx = mesh.getInterpolationMat(bFLocs,'Fx')
                Pby = mesh.getInterpolationMat(bFLocs,'Fy')
                Pbz = mesh.getInterpolationMat(bFLocs,'Fz')
                # Get the fields at location
                # px: x-polaration and py: y-polaration.
                abx_px = mkvc(mkvc(f[src,'b_px'],2).T*Pbx.T)
                aby_px = mkvc(mkvc(f[src,'b_px'],2).T*Pby.T)
                abz_px = mkvc(mkvc(f[src,'b_px'],2).T*Pbz.T)
                abx_py = mkvc(mkvc(f[src,'b_py'],2).T*Pbx.T)
                aby_py = mkvc(mkvc(f[src,'b_py'],2).T*Pby.T)
                abz_py = mkvc(mkvc(f[src,'b_py'],2).T*Pbz.T)
                # Derivatives as lambda functions
                abx_px_u = lambda vec: f._b_pxDeriv_u(src,Pbx.T*vec,adjoint=True)
                aby_px_u = lambda vec: f._b_pxDeriv_u(src,Pby.T*vec,adjoint=True)
                abz_px_u = lambda vec: f._b_pxDeriv_u(src,Pbz.T*vec,adjoint=True)
                abx_py_u = lambda vec: f._b_pyDeriv_u(src,Pbx.T*vec,adjoint=True)
                aby_py_u = lambda vec: f._b_pyDeriv_u(src,Pby.T*vec,adjoint=True)
                abz_py_u = lambda vec: f._b_pyDeriv_u(src,Pbz.T*vec,adjoint=True)

                # Update the input vector
                # Define shortcuts
                sDiag = lambda t: Utils.sdiag(mkvc(t,2))
                sVec = lambda t: Utils.sp.csr_matrix(mkvc(t,2))
                # Define the components of the derivative
                aHd = sDiag(1./(sDiag(abx_px)*aby_py - sDiag(abx_py)*aby_px))
                aHd_uV = lambda x: abx_px_u(sDiag(aby_py)*x) + abx_px_u(sDiag(aby_py)*x) - aby_px_u(sDiag(abx_py)*x) - abx_py_u(sDiag(aby_px)*x)
                # Need to fix this to reflect the adjoint
                if 'tzx' in self.rxType:
                    Tij = sDiag(aHd*( -sDiag(abz_py)*aby_px + sDiag(abz_px)*aby_py))
                    TijN_uV = lambda x: -abz_py_u(sDiag(aby_px)*x) - aby_px_u(sDiag(abz_py)*x) + aby_py_u(sDiag(abz_px)*x) + abz_px_u(sDiag(aby_py)*x)
                elif 'tzy' in self.rxType:
                    Tij = sDiag(aHd*( sDiag(abz_py)*abx_px - sDiag(abz_px)*abx_py))
                    TijN_uV = lambda x: abx_px_u(sDiag(abz_py)*x) + abz_py_u(sDiag(abx_px)*x) - abx_py_u(sDiag(abz_px)*x) - abz_px_u(sDiag(abx_py)*x)
                # Calculate the complex derivative
                PDeriv_real = TijN_uV(aHd*v) - aHd_uV(Tij.T*aHd*v)#
                # NOTE: Need to reshape the output to go from 2*nU array to a (nU,2) matrix for each polarization
                # PDeriv_real = np.hstack((mkvc(PDeriv_real[:len(PDeriv_real)/2],2),mkvc(PDeriv_real[len(PDeriv_real)/2::],2)))
                PDeriv_real = PDeriv_real.reshape((2,mesh.nE)).T
            # Extract the data
            if real_or_imag == 'imag':
                Pv = 1j*PDeriv_real
            elif real_or_imag == 'real':
                Pv = PDeriv_real.astype(complex)


        return Pv
Exemple #18
0
def plot_pseudoSection(DCsurvey, axs, stype):
    """
        Read list of 2D tx-rx location and plot a speudo-section of apparent
        resistivity.

        Assumes flat topo for now...

        Input:
        :param d2D, z0
        :switch stype -> Either 'pdp' (pole-dipole) | 'dpdp' (dipole-dipole)

        Output:
        :figure scatter plot overlayed on image

        Edited Feb 17th, 2016

        @author: dominiquef

    """
    from SimPEG import np
    from scipy.interpolate import griddata
    import pylab as plt

    # Set depth to 0 for now
    z0 = 0.

    # Pre-allocate
    midx = []
    midz = []
    rho = []
    count = 0 # Counter for data
    for ii in range(DCsurvey.nSrc):

        Tx = DCsurvey.srcList[ii].loc
        Rx = DCsurvey.srcList[ii].rxList[0].locs

        nD = DCsurvey.srcList[ii].rxList[0].nD

        data = DCsurvey.dobs[count:count+nD]
        count += nD

        # Get distances between each poles A-B-M-N
        MA = np.abs(Tx[0][0] - Rx[0][:,0])
        MB = np.abs(Tx[1][0] - Rx[0][:,0])
        NB = np.abs(Tx[1][0] - Rx[1][:,0])
        NA = np.abs(Tx[0][0] - Rx[1][:,0])
        MN = np.abs(Rx[1][:,0] - Rx[0][:,0])

        # Create mid-point location
        Cmid = (Tx[0][0] + Tx[1][0])/2
        Pmid = (Rx[0][:,0] + Rx[1][:,0])/2

        # Compute pant leg of apparent rho
        if stype == 'pdp':
            leg =  data * 2*np.pi  * MA * ( MA + MN ) / MN

            leg = np.log10(abs(1/leg))

        elif stype == 'dpdp':
            leg = data * 2*np.pi / ( 1/MA - 1/MB - 1/NB + 1/NA )


        midx = np.hstack([midx, ( Cmid + Pmid )/2 ])
        midz = np.hstack([midz, -np.abs(Cmid-Pmid)/2 + z0 ])
        rho = np.hstack([rho,leg])


    ax = axs

    # Grid points
    grid_x, grid_z = np.mgrid[np.min(midx):np.max(midx), np.min(midz):np.max(midz)]
    grid_rho = griddata(np.c_[midx,midz], rho.T, (grid_x, grid_z), method='linear')


    plt.imshow(grid_rho.T, extent = (np.min(midx),np.max(midx),np.min(midz),np.max(midz)), origin='lower', alpha=0.8, vmin = np.min(rho), vmax = np.max(rho))
    cbar = plt.colorbar(format = '%.2f',fraction=0.04,orientation="horizontal")

    cmin,cmax = cbar.get_clim()
    ticks = np.linspace(cmin,cmax,3)
    cbar.set_ticks(ticks)

    # Plot apparent resistivity
    plt.scatter(midx,midz,s=50,c=rho.T)

    ax.set_xticklabels([])

    ax.set_ylabel('Z')
    ax.yaxis.tick_right()
    ax.yaxis.set_label_position('right')
    plt.gca().set_aspect('equal', adjustable='box')


    return ax
Exemple #19
0
def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None):
    """
        Read list of 2D tx-rx location and plot a speudo-section of apparent
        resistivity.

        Assumes flat topo for now...

        Input:
        :param d2D, z0
        :switch stype -> Either 'pdp' (pole-dipole) | 'dpdp' (dipole-dipole)
        :switch dtype=-> Either 'appr' (app. res) | 'appc' (app. con) | 'volt' (potential)
        Output:
        :figure scatter plot overlayed on image

        Edited Feb 17th, 2016

        @author: dominiquef

    """
    from SimPEG import np
    from scipy.interpolate import griddata
    import pylab as plt

    # Set depth to 0 for now
    z0 = 0.

    # Pre-allocate
    midx = []
    midz = []
    rho = []
    LEG = []
    count = 0  # Counter for data
    for ii in range(DCsurvey.nSrc):

        Tx = DCsurvey.srcList[ii].loc
        Rx = DCsurvey.srcList[ii].rxList[0].locs

        nD = DCsurvey.srcList[ii].rxList[0].nD

        data = DCsurvey.dobs[count:count + nD]
        count += nD

        # Get distances between each poles A-B-M-N
        if stype == 'pdp':
            MA = np.abs(Tx[0] - Rx[0][:, 0])
            NA = np.abs(Tx[0] - Rx[1][:, 0])
            MN = np.abs(Rx[1][:, 0] - Rx[0][:, 0])

            # Create mid-point location
            Cmid = Tx[0]
            Pmid = (Rx[0][:, 0] + Rx[1][:, 0]) / 2
            if DCsurvey.mesh.dim == 2:
                zsrc = Tx[1]
            elif DCsurvey.mesh.dim == 3:
                zsrc = Tx[2]

        elif stype == 'dpdp':
            MA = np.abs(Tx[0][0] - Rx[0][:, 0])
            MB = np.abs(Tx[1][0] - Rx[0][:, 0])
            NA = np.abs(Tx[0][0] - Rx[1][:, 0])
            NB = np.abs(Tx[1][0] - Rx[1][:, 0])

            # Create mid-point location
            Cmid = (Tx[0][0] + Tx[1][0]) / 2
            Pmid = (Rx[0][:, 0] + Rx[1][:, 0]) / 2
            if DCsurvey.mesh.dim == 2:
                zsrc = (Tx[0][1] + Tx[1][1]) / 2
            elif DCsurvey.mesh.dim == 3:
                zsrc = (Tx[0][2] + Tx[1][2]) / 2

        # Change output for dtype
        if dtype == 'volt':

            rho = np.hstack([rho, data])

        else:

            # Compute pant leg of apparent rho
            if stype == 'pdp':

                leg = data * 2 * np.pi * MA * (MA + MN) / MN

            elif stype == 'dpdp':

                leg = data * 2 * np.pi / (1 / MA - 1 / MB + 1 / NB - 1 / NA)
                LEG.append(1. / (2 * np.pi) *
                           (1 / MA - 1 / MB + 1 / NB - 1 / NA))
            else:
                print """dtype must be 'pdp'(pole-dipole) | 'dpdp' (dipole-dipole) """
                break

            if dtype == 'appc':

                leg = np.log10(abs(1. / leg))
                rho = np.hstack([rho, leg])

            elif dtype == 'appr':

                leg = np.log10(abs(leg))
                rho = np.hstack([rho, leg])

            else:
                print """dtype must be 'appr' | 'appc' | 'volt' """
                break

        midx = np.hstack([midx, (Cmid + Pmid) / 2])
        if DCsurvey.mesh.dim == 3:
            midz = np.hstack([midz, -np.abs(Cmid - Pmid) / 2 + zsrc])
        elif DCsurvey.mesh.dim == 2:
            midz = np.hstack([midz, -np.abs(Cmid - Pmid) / 2 + zsrc])
    ax = axs

    # Grid points
    grid_x, grid_z = np.mgrid[np.min(midx):np.max(midx),
                              np.min(midz):np.max(midz)]
    grid_rho = griddata(np.c_[midx, midz],
                        rho.T, (grid_x, grid_z),
                        method='linear')

    if clim == None:
        vmin, vmax = rho.min(), rho.max()
    else:
        vmin, vmax = clim[0], clim[1]

    grid_rho = np.ma.masked_where(np.isnan(grid_rho), grid_rho)
    ph = plt.pcolormesh(grid_x[:, 0],
                        grid_z[0, :],
                        grid_rho.T,
                        clim=(vmin, vmax),
                        vmin=vmin,
                        vmax=vmax)
    cbar = plt.colorbar(format="$10^{%.1f}$",
                        fraction=0.04,
                        orientation="horizontal")

    cmin, cmax = cbar.get_clim()
    ticks = np.linspace(cmin, cmax, 3)
    cbar.set_ticks(ticks)
    cbar.ax.tick_params(labelsize=10)

    if dtype == 'appc':
        cbar.set_label("App.Cond", size=12)
    elif dtype == 'appr':
        cbar.set_label("App.Res.", size=12)
    elif dtype == 'volt':
        cbar.set_label("Potential (V)", size=12)

    # Plot apparent resistivity
    ax.scatter(midx,
               midz,
               s=10,
               c=rho.T,
               vmin=vmin,
               vmax=vmax,
               clim=(vmin, vmax))

    #ax.set_xticklabels([])
    #ax.set_yticklabels([])

    plt.gca().set_aspect('equal', adjustable='box')

    return ph, LEG
def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', plotIt=True):
    """
        DC Forward Simulation
        =====================

        Forward model conductive spheres in a half-space and plot a pseudo-section

        Created by @fourndo on Mon Feb 01 19:28:06 2016

    """

    assert stype in ['pdp', 'dpdp'], "Source type (stype) must be pdp or dpdp (pole dipole or dipole dipole)"


    if loc is None:
        loc = np.c_[[-50.,0.,-50.],[50.,0.,-50.]]
    if sig is None:
        sig = np.r_[1e-2,1e-1,1e-3]
    if radi is None:
        radi = np.r_[25.,25.]
    if param is None:
        param = np.r_[30.,30.,5]


    # First we need to create a mesh and a model.

    # This is our mesh
    dx    = 5.

    hxind = [(dx,15,-1.3), (dx, 75), (dx,15,1.3)]
    hyind = [(dx,15,-1.3), (dx, 10), (dx,15,1.3)]
    hzind = [(dx,15,-1.3),(dx, 15)]

    mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN')


    # Set background conductivity
    model = np.ones(mesh.nC) * sig[0]

    # First anomaly
    ind = Utils.ModelBuilder.getIndicesSphere(loc[:,0],radi[0],mesh.gridCC)
    model[ind] = sig[1]

    # Second anomaly
    ind = Utils.ModelBuilder.getIndicesSphere(loc[:,1],radi[1],mesh.gridCC)
    model[ind] = sig[2]

    # Get index of the center
    indy = int(mesh.nCy/2)


    # Plot the model for reference
    # Define core mesh extent
    xlim = 200
    zlim = 125

    # Specify the survey type: "pdp" | "dpdp"


    # Then specify the end points of the survey. Let's keep it simple for now and survey above the anomalies, top of the mesh
    ends = [(-175,0),(175,0)]
    ends = np.c_[np.asarray(ends),np.ones(2).T*mesh.vectorNz[-1]]

    # Snap the endpoints to the grid. Easier to create 2D section.
    indx = Utils.closestPoints(mesh, ends )
    locs = np.c_[mesh.gridCC[indx,0],mesh.gridCC[indx,1],np.ones(2).T*mesh.vectorNz[-1]]

    # We will handle the geometry of the survey for you and create all the combination of tx-rx along line
    # [Tx, Rx] = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2])
    survey, Tx, Rx = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2])

    # Define some global geometry
    dl_len = np.sqrt( np.sum((locs[0,:] - locs[1,:])**2) )
    dl_x = ( Tx[-1][0,1] - Tx[0][0,0] ) / dl_len
    dl_y = ( Tx[-1][1,1] - Tx[0][1,0]  ) / dl_len
    azm =  np.arctan(dl_y/dl_x)

    #Set boundary conditions
    mesh.setCellGradBC('neumann')

    # Define the differential operators needed for the DC problem
    Div = mesh.faceDiv
    Grad = mesh.cellGrad
    Msig = Utils.sdiag(1./(mesh.aveF2CC.T*(1./model)))

    A = Div*Msig*Grad

    # Change one corner to deal with nullspace
    A[0,0] = 1
    A = sp.csc_matrix(A)

    # We will solve the system iteratively, so a pre-conditioner is helpful
    # This is simply a Jacobi preconditioner (inverse of the main diagonal)
    dA = A.diagonal()
    P = sp.spdiags(1/dA,0,A.shape[0],A.shape[0])

    # Now we can solve the system for all the transmitters
    # We want to store the data
    data = []

    # There is probably a more elegant way to do this, but we can just for-loop through the transmitters
    for ii in range(len(Tx)):

        start_time = time.time() # Let's time the calculations

        #print("Transmitter %i / %i\r" % (ii+1,len(Tx)))

        # Select dipole locations for receiver
        rxloc_M = np.asarray(Rx[ii][:,0:3])
        rxloc_N = np.asarray(Rx[ii][:,3:])


        # For usual cases "dpdp" or "gradient"
        if stype == 'pdp':
            # Create an "inifinity" pole
            tx =  np.squeeze(Tx[ii][:,0:1])
            tinf = tx + np.array([dl_x,dl_y,0])*dl_len*2
            inds = Utils.closestPoints(mesh, np.c_[tx,tinf].T)
            RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*( [-1] / mesh.vol[inds] )
        else:
            inds = Utils.closestPoints(mesh, np.asarray(Tx[ii]).T )
            RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T, 'CC').T*( [-1,1] / mesh.vol[inds] )

        # Iterative Solve
        Ainvb = sp.linalg.bicgstab(P*A,P*RHS, tol=1e-5)

        # We now have the potential everywhere
        phi = Utils.mkvc(Ainvb[0])

        # Solve for phi on pole locations
        P1 = mesh.getInterpolationMat(rxloc_M, 'CC')
        P2 = mesh.getInterpolationMat(rxloc_N, 'CC')

        # Compute the potential difference
        dtemp = (P1*phi - P2*phi)*np.pi

        data.append( dtemp )
        print '\rTransmitter {0} of {1} -> Time:{2} sec'.format(ii,len(Tx),time.time()- start_time),

    print 'Transmitter {0} of {1}'.format(ii,len(Tx))
    print 'Forward completed'

    # Let's just convert the 3D format into 2D (distance along line) and plot
    # [Tx2d, Rx2d] = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc))
    survey2D = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc))
    survey2D.dobs =np.hstack(data)
    # Here is an example for the first tx-rx array
    if plotIt:
        import matplotlib.pyplot as plt
        fig = plt.figure()
        ax = plt.subplot(2,1,1, aspect='equal')
        mesh.plotSlice(np.log10(model), ax =ax, normal = 'Y', ind = indy,grid=True)
        ax.set_title('E-W section at '+str(mesh.vectorCCy[indy])+' m')
        plt.gca().set_aspect('equal', adjustable='box')

        plt.scatter(Tx[0][0,:],Tx[0][2,:],s=40,c='g', marker='v')
        plt.scatter(Rx[0][:,0::3],Rx[0][:,2::3],s=40,c='y')
        plt.xlim([-xlim,xlim])
        plt.ylim([-zlim,mesh.vectorNz[-1]+dx])


        ax = plt.subplot(2,1,2, aspect='equal')

        # Plot the location of the spheres for reference
        circle1=plt.Circle((loc[0,0]-Tx[0][0,0],loc[2,0]),radi[0],color='w',fill=False, lw=3)
        circle2=plt.Circle((loc[0,1]-Tx[0][0,0],loc[2,1]),radi[1],color='k',fill=False, lw=3)
        ax.add_artist(circle1)
        ax.add_artist(circle2)

        # Add the speudo section
        DC.plot_pseudoSection(survey2D,ax,stype)

        # plt.scatter(Tx2d[0][:],Tx[0][2,:],s=40,c='g', marker='v')
        # plt.scatter(Rx2d[0][:],Rx[0][:,2::3],s=40,c='y')
        # plt.plot(np.r_[Tx2d[0][0],Rx2d[-1][-1,-1]],np.ones(2)*mesh.vectorNz[-1], color='k')
        plt.ylim([-zlim,mesh.vectorNz[-1]+dx])

        plt.show()

        return fig, ax
Exemple #21
0
def animate(ii):

    #for ii in range(1):
    removeFrame()
    # Grab current line and
    indx = np.where(lineID == ii)[0]

    srcLeft = []
    obs_l = []
    obs = []
    srcRight = []
    obs_r = []
    srcList = []
    # Split the obs file into left and right
    # Split the obs file into left and right
    for jj in range(len(indx)):

        # Grab corresponding data
        obs = np.hstack([obs, DCdobs2D.dobs[dataID == indx[jj]]])
        #std = dobs2D.std[dataID==indx[jj]]

        srcList.append(DCdobs2D.srcList[indx[jj]])

        Tx = DCdobs2D.srcList[indx[jj]].loc
        Rx = DCdobs2D.srcList[indx[jj]].rxList[0].locs

        # Create mid-point location
        Cmid = (Tx[0][0] + Tx[1][0]) / 2
        Pmid = (Rx[0][:, 0] + Rx[1][:, 0]) / 2

        ileft = Pmid < Cmid
        iright = Pmid >= Cmid

        temp = np.zeros(len(ileft))
        temp[ileft] = 1
        obs_l = np.hstack([obs_l, temp])

        temp = np.zeros(len(iright))
        temp[iright] = 1
        obs_r = np.hstack([obs_r, temp])

        if np.any(ileft):
            rx = DC.RxDipole(Rx[0][ileft, :], Rx[1][ileft, :])
            srcLeft.append(DC.SrcDipole([rx], Tx[0], Tx[1]))

            #std_l = np.hstack([std_l,std[ileft]])

        if np.any(iright):
            rx = DC.RxDipole(Rx[0][iright, :], Rx[1][iright, :])
            srcRight.append(DC.SrcDipole([rx], Tx[0], Tx[1]))

            #obs_r = np.hstack([obs_r,iright])
            #std_r = np.hstack([std_r,std[iright]])

    DC2D_full = DC.SurveyDC(srcList)
    DC2D_full.dobs = np.asarray(obs)
    DC2D_full.std = DC2D_full.dobs * 0.
    DC2D_full.std[obs_l ==
                  1] = np.abs(DC2D_full.dobs[obs_l == 1]) * 0.02 + 2e-5
    DC2D_full.std[obs_r ==
                  1] = np.abs(DC2D_full.dobs[obs_r == 1]) * 0.06 + 4e-5

    #    DC2D_l = DC.SurveyDC(srcLeft)
    #    DC2D_l.dobs = np.asarray(obs[obs_l==1])
    #    DC2D_l.std = np.abs(np.asarray(DC2D_l.dobs))*0.05 + 2e-5
    #
    #    DC2D_r = DC.SurveyDC(srcRight)
    #    DC2D_r.dobs = np.asarray(obs[obs_r==1])
    #    DC2D_r.std = np.abs(np.asarray(DC2D_r.dobs))*0.05 + 2e-5

    survey = DC2D_full

    # Export data file
    DC.writeUBC_DCobs(inv_dir + dsep + obsfile2d, survey, '2D', 'SIMPLE')

    # Write input file
    fid = open(inv_dir + dsep + inp_file, 'w')
    fid.write('OBS LOC_X %s \n' % obsfile2d)
    fid.write('MESH FILE %s \n' % mshfile2d)
    fid.write('CHIFACT 1 \n')
    fid.write('TOPO DEFAULT \n')
    fid.write('INIT_MOD VALUE %e\n' % ini_mod)
    fid.write('REF_MOD VALUE %e\n' % ref_mod)
    fid.write('ALPHA VALUE %f %f %F\n' % (1. / dx**4., 1, 1))
    fid.write('WEIGHT DEFAULT\n')
    fid.write('STORE_ALL_MODELS FALSE\n')
    fid.write('INVMODE CG\n')
    #fid.write('CG_PARAM 200 1e-4\n')
    fid.write('USE_MREF FALSE\n')
    #fid.write('BOUNDS VALUE 1e-4 1e+2\n')
    fid.close()

    os.chdir(inv_dir)
    os.system('dcinv2d ' + inp_file)

    #%% Load DC model and predicted data
    minv = DC.readUBC_DC2DModel(inv_dir + dsep + 'dcinv2d.con')
    minv = np.reshape(minv, (mesh2d.nCy, mesh2d.nCx))

    #%% Repeat for IP data
    indx = np.where(IPlineID == ii)[0]

    srcLeft = []
    obs_l = []
    std_l = []

    srcRight = []
    obs_r = []
    std_r = []

    obs_full = []
    std_full = []
    srcList = []

    # Split the obs file into left and right
    for jj in range(len(indx)):

        srcList.append(IPdobs2D.srcList[indx[jj]])
        # Grab corresponding data
        obs = IPdobs2D.dobs[IPdataID == indx[jj]]
        std = IPdobs2D.std[IPdataID == indx[jj]]

        obs_full = np.hstack([obs_full, obs])
        std_full = np.hstack([std_full, std])

        Tx = IPdobs2D.srcList[indx[jj]].loc
        Rx = IPdobs2D.srcList[indx[jj]].rxList[0].locs

        # Create mid-point location
        Cmid = (Tx[0][0] + Tx[1][0]) / 2
        Pmid = (Rx[0][:, 0] + Rx[1][:, 0]) / 2

        ileft = Pmid < Cmid
        iright = Pmid >= Cmid

        temp = np.zeros(len(ileft))
        temp[ileft] = 1
        obs_l = np.hstack([obs_l, temp])

        temp = np.zeros(len(iright))
        temp[iright] = 1
        obs_r = np.hstack([obs_r, temp])

        if np.any(ileft):
            rx = DC.RxDipole(Rx[0][ileft, :], Rx[1][ileft, :])
            srcLeft.append(DC.SrcDipole([rx], Tx[0], Tx[1]))

            #std_l = np.hstack([std_l,std[ileft]])

        if np.any(iright):
            rx = DC.RxDipole(Rx[0][iright, :], Rx[1][iright, :])
            srcRight.append(DC.SrcDipole([rx], Tx[0], Tx[1]))

    IP2D_full = DC.SurveyDC(srcList)
    IP2D_full.dobs = np.asarray(obs_full)
    IP2D_full.std = np.asarray(std_full)

    IP2D_l = DC.SurveyDC(srcLeft)
    IP2D_l.dobs = np.asarray(obs_full[obs_l == 1])
    #IP2D_l.std = np.abs(np.asarray(obs_l))*0.03 + 2e-2

    IP2D_r = DC.SurveyDC(srcRight)
    IP2D_r.dobs = np.asarray(obs_full[obs_r == 1])
    #IP2D_r.std = np.abs(np.asarray(obs_r))*0.03 + 1e-2

    id_lbe = int(IPsurvey.srcList[indx[jj]].loc[0][1])

    mesh3d = Mesh.TensorMesh([hx, np.ones(1) * 100., hz],
                             x0=(-np.sum(padx) + np.min(srcMat[0][:, 0]),
                                 id_lbe - 50,
                                 np.max(srcMat[0][0, 2]) - np.sum(hz)))
    Mesh.TensorMesh.writeUBC(mesh3d,
                             home_dir + dsep + 'Mesh' + str(id_lbe) + '.msh')
    global ax1, ax2, ax3, ax5, ax6, fig

    ax2 = plt.subplot(3, 2, 2)
    ph = DC.plot_pseudoSection(IP2D_r,
                               ax2,
                               stype='pdp',
                               dtype='volt',
                               colorbar=False)
    ax2.set_title('Observed P-DP', fontsize=10)
    plt.xlim([xmin, xmax])
    plt.ylim([zmin, zmax])
    plt.gca().set_aspect('equal', adjustable='box')
    ax2.set_xticklabels([])
    ax2.set_yticklabels([])

    ax1 = plt.subplot(3, 2, 1)
    DC.plot_pseudoSection(IP2D_l,
                          ax1,
                          stype='pdp',
                          dtype='volt',
                          clim=(ph[0].get_clim()[0], ph[0].get_clim()[1]),
                          colorbar=False)
    ax1.set_title('Observed DP-P', fontsize=10)
    plt.xlim([xmin, xmax])
    plt.ylim([zmin, zmax])
    plt.gca().set_aspect('equal', adjustable='box')
    ax1.set_xticklabels([])
    z = np.linspace(np.min(ph[2]), np.max(ph[2]), 5)
    z_label = np.linspace(20, 1, 5)
    ax1.set_yticks(map(int, z))
    ax1.set_yticklabels(map(str, map(int, z_label)), size=8)
    ax1.set_ylabel('n-spacing', fontsize=8)

    #%% Add labels
    bbox_props = dict(boxstyle="circle,pad=0.3", fc="r", ec="k", lw=1)
    ax2.text(0.00,
             1,
             'A',
             transform=ax2.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    bbox_props = dict(boxstyle="circle,pad=0.3", fc="y", ec="k", lw=1)
    ax2.text(0.1,
             1,
             'M',
             transform=ax2.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    bbox_props = dict(boxstyle="circle,pad=0.3", fc="g", ec="k", lw=1)
    ax2.text(0.2,
             1,
             'N',
             transform=ax2.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    bbox_props = dict(boxstyle="circle,pad=0.3", fc="g", ec="k", lw=1)
    ax1.text(0.00,
             1,
             'N',
             transform=ax1.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    bbox_props = dict(boxstyle="circle,pad=0.3", fc="y", ec="k", lw=1)
    ax1.text(0.1,
             1,
             'M',
             transform=ax1.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    bbox_props = dict(boxstyle="circle,pad=0.3", fc="r", ec="k", lw=1)
    ax1.text(0.2,
             1,
             'A',
             transform=ax1.transAxes,
             ha="left",
             va="center",
             size=6,
             bbox=bbox_props)

    survey = IP2D_full

    # Export data file
    DC.writeUBC_DCobs(inv_dir + dsep + ipfile2d,
                      survey,
                      '2D',
                      'SIMPLE',
                      iptype=1)

    fid = open(inv_dir + dsep + inp_file, 'w')
    fid.write('OBS LOC_X %s \n' % ipfile2d)
    fid.write('MESH FILE %s \n' % mshfile2d)
    fid.write('CHIFACT 4 \n')
    fid.write('COND FILE dcinv2d.con\n')
    fid.write('TOPO DEFAULT \n')
    fid.write('INIT_MOD VALUE %e\n' % ini_mod)
    fid.write('REF_MOD VALUE 0.0\n')
    fid.write('ALPHA VALUE %f %f %F\n' % (1. / dx**4., 1, 1))
    fid.write('WEIGHT DEFAULT\n')
    fid.write('STORE_ALL_MODELS FALSE\n')
    fid.write('INVMODE CG\n')
    #fid.write('CG_PARAM 200 1e-4\n')
    fid.write('USE_MREF FALSE\n')
    #fid.write('BOUNDS VALUE 1e-4 1e+2\n')
    fid.close()

    os.chdir(inv_dir)
    os.system('ipinv2d ' + inp_file)

    #%% Load model and predicted data
    minv = DC.readUBC_DC2DModel(inv_dir + dsep + 'ipinv2d.chg')
    minv = np.reshape(minv, (mesh2d.nCy, mesh2d.nCx))

    Mesh.TensorMesh.writeModelUBC(
        mesh3d, home_dir + dsep + 'Model' + str(id_lbe) + '.chg', minv.T)

    dpre = DC.readUBC_DC2Dpre(inv_dir + dsep + 'ipinv2d.pre')
    DCpre = dpre['DCsurvey']

    DCtemp = IP2D_l
    DCtemp.dobs = DCpre.dobs[obs_l == 1]

    ax5 = plt.subplot(3, 2, 3)
    DC.plot_pseudoSection(DCtemp,
                          ax5,
                          stype='pdp',
                          dtype='volt',
                          clim=(ph[0].get_clim()[0], ph[0].get_clim()[1]),
                          colorbar=False)
    ax5.set_title('Predicted', fontsize=10)
    plt.xlim([xmin, xmax])
    plt.ylim([zmin, zmax])
    plt.gca().set_aspect('equal', adjustable='box')
    ax5.set_xticklabels([])
    z = np.linspace(np.min(ph[2]), np.max(ph[2]), 5)
    z_label = np.linspace(20, 1, 5)
    ax5.set_yticks(map(int, z))
    ax5.set_yticklabels(map(str, map(int, z_label)), size=8)
    ax5.set_ylabel('n-spacing', fontsize=8)

    DCtemp = IP2D_r
    DCtemp.dobs = DCpre.dobs[obs_r == 1]

    ax6 = plt.subplot(3, 2, 4)
    DC.plot_pseudoSection(DCtemp,
                          ax6,
                          stype='pdp',
                          dtype='volt',
                          clim=(ph[0].get_clim()[0], ph[0].get_clim()[1]),
                          colorbar=False)
    ax6.set_title('Predicted', fontsize=10)
    plt.xlim([xmin, xmax])
    plt.ylim([zmin, zmax])
    plt.gca().set_aspect('equal', adjustable='box')
    ax6.set_xticklabels([])
    ax6.set_yticklabels([])

    pos = ax6.get_position()
    cbarax = fig.add_axes([
        pos.x0 + 0.325, pos.y0 + 0.2, pos.width * 0.1, pos.height * 0.5
    ])  ## the parameters are the specified position you set
    cb = fig.colorbar(ph[0],
                      cax=cbarax,
                      orientation="vertical",
                      ax=ax6,
                      ticks=np.linspace(ph[0].get_clim()[0],
                                        ph[0].get_clim()[1], 4),
                      format="$10^{%.1f}$")
    cb.set_label("App. Charg.", size=8)

    ax3 = plt.subplot(3, 1, 3)
    ax3.set_title('2-D Model (S/m)', fontsize=10)
    ax3.set_xticks(map(int, x))
    ax3.set_xticklabels(map(str, map(int, x)))
    ax3.set_xlabel('Easting (m)', fontsize=8)
    ax3.set_yticks(map(int, z))
    ax3.set_yticklabels(map(str, map(int, z)), rotation='vertical')
    ax3.set_ylabel('Depth (m)', fontsize=8)

    plt.xlim([xmin, xmax])
    plt.ylim([zmin / 2, zmax])
    plt.gca().set_aspect('equal', adjustable='box')

    ph2 = plt.pcolormesh(mesh2d.vectorNx,
                         mesh2d.vectorNy, (minv),
                         vmin=vmin,
                         vmax=vmax)
    plt.gca().tick_params(axis='both', which='major', labelsize=8)

    plt.draw()

    for ss in range(survey.nSrc):
        Tx = survey.srcList[ss].loc[0]
        plt.scatter(Tx[0], mesh2d.vectorNy[-1] + 10, s=10)

    pos = ax3.get_position()
    ax3.set_position([pos.x0 + 0.025, pos.y0, pos.width, pos.height])
    pos = ax3.get_position()
    cbarax = fig.add_axes([
        pos.x0 + 0.65, pos.y0 + 0.01, pos.width * 0.05, pos.height * 0.75
    ])  ## the parameters are the specified position you set
    cb = fig.colorbar(ph2,
                      cax=cbarax,
                      orientation="vertical",
                      ax=ax3,
                      ticks=np.linspace(vmin, vmax, 4),
                      format="%4.1f")
    cb.set_label("Chargeability", size=8)

    pos = ax1.get_position()
    ax1.set_position([pos.x0 + 0.03, pos.y0, pos.width, pos.height])

    pos = ax5.get_position()
    ax5.set_position([pos.x0 + 0.03, pos.y0, pos.width, pos.height])

    pos = ax2.get_position()
    ax2.set_position([pos.x0 - 0.03, pos.y0, pos.width, pos.height])

    pos = ax6.get_position()
    ax6.set_position([pos.x0 - 0.03, pos.y0, pos.width, pos.height])

    #%% Add the extra

    bbox_props = dict(boxstyle="rarrow,pad=0.3", fc="w", ec="k", lw=2)
    ax2.text(0.01, (float(ii) + 1.) / (len(uniqueID) + 2),
             'N: ' + str(id_lbe),
             transform=fig.transFigure,
             ha="left",
             va="center",
             size=8,
             bbox=bbox_props)

    mrk_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=2)
    ax2.text(0.01,
             0.9,
             'Line ID#',
             transform=fig.transFigure,
             ha="left",
             va="center",
             size=8,
             bbox=mrk_props)

    mrk_props = dict(boxstyle="square,pad=0.3", fc="b", ec="k", lw=2)

    for jj in range(len(uniqueID)):
        ax2.text(0.1, (float(jj) + 1.) / (len(uniqueID) + 2),
                 ".",
                 transform=fig.transFigure,
                 ha="right",
                 va="center",
                 size=8,
                 bbox=mrk_props)

    mrk_props = dict(boxstyle="square,pad=0.3", fc="r", ec="k", lw=2)

    ax2.text(0.1, (float(ii) + 1.) / (len(uniqueID) + 2),
             ".",
             transform=fig.transFigure,
             ha="right",
             va="center",
             size=8,
             bbox=mrk_props)
def run(loc=None, sig=None, radi=None, param=None, stype='dpdp', plotIt=True):
    """
        DC Forward Simulation
        =====================

        Forward model conductive spheres in a half-space and plot a pseudo-section

        Created by @fourndo on Mon Feb 01 19:28:06 2016

    """

    assert stype in [
        'pdp', 'dpdp'
    ], "Source type (stype) must be pdp or dpdp (pole dipole or dipole dipole)"

    if loc is None:
        loc = np.c_[[-50., 0., -50.], [50., 0., -50.]]
    if sig is None:
        sig = np.r_[1e-2, 1e-1, 1e-3]
    if radi is None:
        radi = np.r_[25., 25.]
    if param is None:
        param = np.r_[30., 30., 5]

    # First we need to create a mesh and a model.

    # This is our mesh
    dx = 5.

    hxind = [(dx, 15, -1.3), (dx, 75), (dx, 15, 1.3)]
    hyind = [(dx, 15, -1.3), (dx, 10), (dx, 15, 1.3)]
    hzind = [(dx, 15, -1.3), (dx, 15)]

    mesh = Mesh.TensorMesh([hxind, hyind, hzind], 'CCN')

    # Set background conductivity
    model = np.ones(mesh.nC) * sig[0]

    # First anomaly
    ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 0], radi[0], mesh.gridCC)
    model[ind] = sig[1]

    # Second anomaly
    ind = Utils.ModelBuilder.getIndicesSphere(loc[:, 1], radi[1], mesh.gridCC)
    model[ind] = sig[2]

    # Get index of the center
    indy = int(mesh.nCy / 2)

    # Plot the model for reference
    # Define core mesh extent
    xlim = 200
    zlim = 125

    # Specify the survey type: "pdp" | "dpdp"

    # Then specify the end points of the survey. Let's keep it simple for now and survey above the anomalies, top of the mesh
    ends = [(-175, 0), (175, 0)]
    ends = np.c_[np.asarray(ends), np.ones(2).T * mesh.vectorNz[-1]]

    # Snap the endpoints to the grid. Easier to create 2D section.
    indx = Utils.closestPoints(mesh, ends)
    locs = np.c_[mesh.gridCC[indx, 0], mesh.gridCC[indx, 1],
                 np.ones(2).T * mesh.vectorNz[-1]]

    # We will handle the geometry of the survey for you and create all the combination of tx-rx along line
    # [Tx, Rx] = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1], param[2])
    survey, Tx, Rx = DC.gen_DCIPsurvey(locs, mesh, stype, param[0], param[1],
                                       param[2])

    # Define some global geometry
    dl_len = np.sqrt(np.sum((locs[0, :] - locs[1, :])**2))
    dl_x = (Tx[-1][0, 1] - Tx[0][0, 0]) / dl_len
    dl_y = (Tx[-1][1, 1] - Tx[0][1, 0]) / dl_len
    azm = np.arctan(dl_y / dl_x)

    #Set boundary conditions
    mesh.setCellGradBC('neumann')

    # Define the differential operators needed for the DC problem
    Div = mesh.faceDiv
    Grad = mesh.cellGrad
    Msig = Utils.sdiag(1. / (mesh.aveF2CC.T * (1. / model)))

    A = Div * Msig * Grad

    # Change one corner to deal with nullspace
    A[0, 0] = 1
    A = sp.csc_matrix(A)

    # We will solve the system iteratively, so a pre-conditioner is helpful
    # This is simply a Jacobi preconditioner (inverse of the main diagonal)
    dA = A.diagonal()
    P = sp.spdiags(1 / dA, 0, A.shape[0], A.shape[0])

    # Now we can solve the system for all the transmitters
    # We want to store the data
    data = []

    # There is probably a more elegant way to do this, but we can just for-loop through the transmitters
    for ii in range(len(Tx)):

        start_time = time.time()  # Let's time the calculations

        #print("Transmitter %i / %i\r" % (ii+1,len(Tx)))

        # Select dipole locations for receiver
        rxloc_M = np.asarray(Rx[ii][:, 0:3])
        rxloc_N = np.asarray(Rx[ii][:, 3:])

        # For usual cases "dpdp" or "gradient"
        if stype == 'pdp':
            # Create an "inifinity" pole
            tx = np.squeeze(Tx[ii][:, 0:1])
            tinf = tx + np.array([dl_x, dl_y, 0]) * dl_len * 2
            inds = Utils.closestPoints(mesh, np.c_[tx, tinf].T)
            RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T,
                                           'CC').T * ([-1] / mesh.vol[inds])
        else:
            inds = Utils.closestPoints(mesh, np.asarray(Tx[ii]).T)
            RHS = mesh.getInterpolationMat(np.asarray(Tx[ii]).T,
                                           'CC').T * ([-1, 1] / mesh.vol[inds])

        # Iterative Solve
        Ainvb = sp.linalg.bicgstab(P * A, P * RHS, tol=1e-5)

        # We now have the potential everywhere
        phi = Utils.mkvc(Ainvb[0])

        # Solve for phi on pole locations
        P1 = mesh.getInterpolationMat(rxloc_M, 'CC')
        P2 = mesh.getInterpolationMat(rxloc_N, 'CC')

        # Compute the potential difference
        dtemp = (P1 * phi - P2 * phi) * np.pi

        data.append(dtemp)
        print '\rTransmitter {0} of {1} -> Time:{2} sec'.format(
            ii, len(Tx),
            time.time() - start_time),

    print 'Transmitter {0} of {1}'.format(ii, len(Tx))
    print 'Forward completed'

    # Let's just convert the 3D format into 2D (distance along line) and plot
    # [Tx2d, Rx2d] = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc))
    survey2D = DC.convertObs_DC3D_to_2D(survey, np.ones(survey.nSrc))
    survey2D.dobs = np.hstack(data)
    # Here is an example for the first tx-rx array
    if plotIt:
        import matplotlib.pyplot as plt
        fig = plt.figure()
        ax = plt.subplot(2, 1, 1, aspect='equal')
        mesh.plotSlice(np.log10(model), ax=ax, normal='Y', ind=indy, grid=True)
        ax.set_title('E-W section at ' + str(mesh.vectorCCy[indy]) + ' m')
        plt.gca().set_aspect('equal', adjustable='box')

        plt.scatter(Tx[0][0, :], Tx[0][2, :], s=40, c='g', marker='v')
        plt.scatter(Rx[0][:, 0::3], Rx[0][:, 2::3], s=40, c='y')
        plt.xlim([-xlim, xlim])
        plt.ylim([-zlim, mesh.vectorNz[-1] + dx])

        ax = plt.subplot(2, 1, 2, aspect='equal')

        # Plot the location of the spheres for reference
        circle1 = plt.Circle((loc[0, 0] - Tx[0][0, 0], loc[2, 0]),
                             radi[0],
                             color='w',
                             fill=False,
                             lw=3)
        circle2 = plt.Circle((loc[0, 1] - Tx[0][0, 0], loc[2, 1]),
                             radi[1],
                             color='k',
                             fill=False,
                             lw=3)
        ax.add_artist(circle1)
        ax.add_artist(circle2)

        # Add the speudo section
        DC.plot_pseudoSection(survey2D, ax, stype)

        # plt.scatter(Tx2d[0][:],Tx[0][2,:],s=40,c='g', marker='v')
        # plt.scatter(Rx2d[0][:],Rx[0][:,2::3],s=40,c='y')
        # plt.plot(np.r_[Tx2d[0][0],Rx2d[-1][-1,-1]],np.ones(2)*mesh.vectorNz[-1], color='k')
        plt.ylim([-zlim, mesh.vectorNz[-1] + dx])

        plt.show()

        return fig, ax
Exemple #23
0
 def getUniqueTimes(self):
     time_rx = []
     for src in self.srcList:
         for rx in src.rxList:
             time_rx.append(rx.times)
     self.times = np.unique(np.hstack(time_rx))
Exemple #24
0
    def Jvec(self, m, v, f=None):
        """
        Jvec computes the sensitivity times a vector

        .. math::
            \mathbf{J} \mathbf{v} = \\frac{d\mathbf{P}}{d\mathbf{F}} \left(
            \\frac{d\mathbf{F}}{d\mathbf{u}} \\frac{d\mathbf{u}}{d\mathbf{m}} +
            \\frac{\partial\mathbf{F}}{\partial\mathbf{m}} \\right) \mathbf{v}

        where

        .. math::
            \mathbf{A} \\frac{d\mathbf{u}}{d\mathbf{m}} +
            \\frac{\partial \mathbf{A}(\mathbf{u}, \mathbf{m})}
            {\partial\mathbf{m}} =
            \\frac{d \mathbf{RHS}}{d \mathbf{m}}
        """

        if f is None:
            f = self.fields(m)

        ftype = self._fieldType + 'Solution'  # the thing we solved for
        self.model = m

        # mat to store previous time-step's solution deriv times a vector for
        # each source
        # size: nu x nSrc

        # this is a bit silly

        # if self._fieldType is 'b' or self._fieldType is 'j':
        #     ifields = np.zeros((self.mesh.nF, len(Srcs)))
        # elif self._fieldType is 'e' or self._fieldType is 'h':
        #     ifields = np.zeros((self.mesh.nE, len(Srcs)))

        # for i, src in enumerate(self.survey.srcList):
        dun_dm_v = np.hstack([
            Utils.mkvc(
                self.getInitialFieldsDeriv(src, v), 2
            )
            for src in self.survey.srcList
        ]) # can over-write this at each timestep

        # store the field derivs we need to project to calc full deriv
        df_dm_v = Fields_Derivs(self.mesh, self.survey)

        Adiaginv = None

        for tInd, dt in zip(range(self.nT), self.timeSteps):
            # keep factors if dt is the same as previous step b/c A will be the
            # same
            if Adiaginv is not None and (tInd > 0 and dt !=
                                         self.timeSteps[tInd - 1]):
                Adiaginv.clean()
                Adiaginv = None

            if Adiaginv is None:
                A = self.getAdiag(tInd)
                Adiaginv = self.Solver(A, **self.solverOpts)

            Asubdiag = self.getAsubdiag(tInd)

            for i, src in enumerate(self.survey.srcList):

                # here, we are lagging by a timestep, so filling in as we go
                for projField in set([rx.projField for rx in src.rxList]):
                    df_dmFun = getattr(f, '_%sDeriv' % projField, None)
                    # df_dm_v is dense, but we only need the times at
                    # (rx.P.T * ones > 0)
                    # This should be called rx.footprint

                    df_dm_v[src, '{}Deriv'.format(projField), tInd] = df_dmFun(
                        tInd, src, dun_dm_v[:, i], v
                        )

                un_src = f[src, ftype, tInd+1]

                # cell centered on time mesh
                dA_dm_v = self.getAdiagDeriv(tInd, un_src, v)
                # on nodes of time mesh
                dRHS_dm_v = self.getRHSDeriv(tInd+1, src, v)

                dAsubdiag_dm_v = self.getAsubdiagDeriv(
                    tInd, f[src, ftype, tInd], v
                )

                JRHS = dRHS_dm_v - dAsubdiag_dm_v - dA_dm_v

                # step in time and overwrite
                if tInd != len(self.timeSteps+1):
                    dun_dm_v[:, i] = Adiaginv * (
                        JRHS - Asubdiag * dun_dm_v[:, i]
                    )

        Jv = []
        for src in self.survey.srcList:
            for rx in src.rxList:
                Jv.append(
                    rx.evalDeriv(src, self.mesh, self.timeMesh, f, Utils.mkvc(
                            df_dm_v[src, '%sDeriv' % rx.projField, :]
                        )
                    )
                )
        Adiaginv.clean()
        # del df_dm_v, dun_dm_v, Asubdiag
        # return Utils.mkvc(Jv)
        return np.hstack(Jv)
Exemple #25
0
def plot_pseudoSection(DCsurvey, axs, stype='dpdp', dtype="appc", clim=None):
    """
        Read list of 2D tx-rx location and plot a speudo-section of apparent
        resistivity.

        Assumes flat topo for now...

        Input:
        :param d2D, z0
        :switch stype -> Either 'pdp' (pole-dipole) | 'dpdp' (dipole-dipole)
        :switch dtype=-> Either 'appr' (app. res) | 'appc' (app. con) | 'volt' (potential)
        Output:
        :figure scatter plot overlayed on image

        Edited Feb 17th, 2016

        @author: dominiquef

    """
    from SimPEG import np
    from scipy.interpolate import griddata
    import pylab as plt

    # Set depth to 0 for now
    z0 = 0.

    # Pre-allocate
    midx = []
    midz = []
    rho = []
    LEG = []
    count = 0 # Counter for data
    for ii in range(DCsurvey.nSrc):

        Tx = DCsurvey.srcList[ii].loc
        Rx = DCsurvey.srcList[ii].rxList[0].locs

        nD = DCsurvey.srcList[ii].rxList[0].nD

        data = DCsurvey.dobs[count:count+nD]
        count += nD

        # Get distances between each poles A-B-M-N
        if stype == 'pdp':
            MA = np.abs(Tx[0] - Rx[0][:,0])
            NA = np.abs(Tx[0] - Rx[1][:,0])
            MN = np.abs(Rx[1][:,0] - Rx[0][:,0])

            # Create mid-point location
            Cmid = Tx[0]
            Pmid = (Rx[0][:,0] + Rx[1][:,0])/2
            if DCsurvey.mesh.dim == 2:
                zsrc = Tx[1]
            elif DCsurvey.mesh.dim ==3:
                zsrc = Tx[2]

        elif stype == 'dpdp':
            MA = np.abs(Tx[0][0] - Rx[0][:,0])
            MB = np.abs(Tx[1][0] - Rx[0][:,0])
            NA = np.abs(Tx[0][0] - Rx[1][:,0])
            NB = np.abs(Tx[1][0] - Rx[1][:,0])

            # Create mid-point location
            Cmid = (Tx[0][0] + Tx[1][0])/2
            Pmid = (Rx[0][:,0] + Rx[1][:,0])/2
            if DCsurvey.mesh.dim == 2:
                zsrc = (Tx[0][1] + Tx[1][1])/2
            elif DCsurvey.mesh.dim ==3:
                zsrc = (Tx[0][2] + Tx[1][2])/2

        # Change output for dtype
        if dtype == 'volt':

            rho = np.hstack([rho,data])

        else:

            # Compute pant leg of apparent rho
            if stype == 'pdp':

                leg =  data * 2*np.pi  * MA * ( MA + MN ) / MN

            elif stype == 'dpdp':

                leg = data * 2*np.pi / ( 1/MA - 1/MB + 1/NB - 1/NA )
                LEG.append(1./(2*np.pi) *( 1/MA - 1/MB + 1/NB - 1/NA ))
            else:
                print("""dtype must be 'pdp'(pole-dipole) | 'dpdp' (dipole-dipole) """)
                break


            if dtype == 'appc':

                leg = np.log10(abs(1./leg))
                rho = np.hstack([rho,leg])

            elif dtype == 'appr':

                leg = np.log10(abs(leg))
                rho = np.hstack([rho,leg])

            else:
                print("""dtype must be 'appr' | 'appc' | 'volt' """)
                break


        midx = np.hstack([midx, ( Cmid + Pmid )/2 ])
        if DCsurvey.mesh.dim==3:
            midz = np.hstack([midz, -np.abs(Cmid-Pmid)/2 + zsrc ])
        elif DCsurvey.mesh.dim==2:
            midz = np.hstack([midz, -np.abs(Cmid-Pmid)/2 + zsrc ])
    ax = axs

    # Grid points
    grid_x, grid_z = np.mgrid[np.min(midx):np.max(midx), np.min(midz):np.max(midz)]
    grid_rho = griddata(np.c_[midx,midz], rho.T, (grid_x, grid_z), method='linear')

    if clim == None:
        vmin, vmax = rho.min(), rho.max()
    else:
        vmin, vmax = clim[0], clim[1]

    grid_rho = np.ma.masked_where(np.isnan(grid_rho), grid_rho)
    ph = plt.pcolormesh(grid_x[:,0],grid_z[0,:],grid_rho.T, clim=(vmin, vmax), vmin=vmin, vmax=vmax)
    cbar = plt.colorbar(format="$10^{%.1f}$",fraction=0.04,orientation="horizontal")

    cmin,cmax = cbar.get_clim()
    ticks = np.linspace(cmin,cmax,3)
    cbar.set_ticks(ticks)
    cbar.ax.tick_params(labelsize=10)

    if dtype == 'appc':
        cbar.set_label("App.Cond",size=12)
    elif dtype == 'appr':
        cbar.set_label("App.Res.",size=12)
    elif dtype == 'volt':
        cbar.set_label("Potential (V)",size=12)

    # Plot apparent resistivity
    ax.scatter(midx,midz,s=10,c=rho.T, vmin =vmin, vmax = vmax, clim=(vmin, vmax))

    #ax.set_xticklabels([])
    #ax.set_yticklabels([])

    plt.gca().set_aspect('equal', adjustable='box')



    return ph, LEG
Exemple #26
0
    def toRecArray(self, returnType='RealImag'):
        '''
        Function that returns a numpy.recarray for a SimpegMT impedance data object.

        :param str returnType: Switches between returning a rec array where the impedance is split to real and imaginary ('RealImag') or is a complex ('Complex')

        '''

        # Define the record fields
        dtRI = [('freq', float), ('x', float), ('y', float), ('z', float),
                ('zxxr', float), ('zxxi', float), ('zxyr', float),
                ('zxyi', float), ('zyxr', float), ('zyxi', float),
                ('zyyr', float), ('zyyi', float), ('tzxr', float),
                ('tzxi', float), ('tzyr', float), ('tzyi', float)]
        dtCP = [('freq', float), ('x', float), ('y', float), ('z', float),
                ('zxx', complex), ('zxy', complex), ('zyx', complex),
                ('zyy', complex), ('tzx', complex), ('tzy', complex)]
        impList = [
            'zxxr', 'zxxi', 'zxyr', 'zxyi', 'zyxr', 'zyxi', 'zyyr', 'zyyi'
        ]
        for src in self.survey.srcList:
            # Temp array for all the receivers of the source.
            # Note: needs to be written more generally, using diffterent rxTypes and not all the data at the locaitons
            # Assume the same locs for all RX
            locs = src.rxList[0].locs
            if locs.shape[1] == 1:
                locs = np.hstack((np.array([[0.0, 0.0]]), locs))
            elif locs.shape[1] == 2:
                locs = np.hstack((np.array([[0.0]]), locs))
            tArrRec = np.concatenate((src.freq * np.ones(
                (locs.shape[0], 1)), locs, np.nan * np.ones(
                    (locs.shape[0], 12))),
                                     axis=1).view(dtRI)
            # np.array([(src.freq,rx.locs[0,0],rx.locs[0,1],rx.locs[0,2],np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ,np.nan ) for rx in src.rxList],dtype=dtRI)
            # Get the type and the value for the DataMT object as a list
            typeList = [[rx.rxType.replace('z1d', 'zyx'), self[src, rx]]
                        for rx in src.rxList]
            # Insert the values to the temp array
            for nr, (key, val) in enumerate(typeList):
                tArrRec[key] = mkvc(val, 2)
            # Masked array
            mArrRec = np.ma.MaskedArray(
                rec2ndarr(tArrRec),
                mask=np.isnan(rec2ndarr(tArrRec))).view(dtype=tArrRec.dtype)
            # Unique freq and loc of the masked array
            uniFLmarr = np.unique(mArrRec[['freq', 'x', 'y', 'z']]).copy()

            try:
                outTemp = recFunc.stack_arrays((outTemp, mArrRec))
                #outTemp = np.concatenate((outTemp,dataBlock),axis=0)
            except NameError as e:
                outTemp = mArrRec

            if 'RealImag' in returnType:
                outArr = outTemp
            elif 'Complex' in returnType:
                # Add the real and imaginary to a complex number
                outArr = np.empty(outTemp.shape, dtype=dtCP)
                for comp in ['freq', 'x', 'y', 'z']:
                    outArr[comp] = outTemp[comp].copy()
                for comp in ['zxx', 'zxy', 'zyx', 'zyy', 'tzx', 'tzy']:
                    outArr[comp] = outTemp[
                        comp + 'r'].copy() + 1j * outTemp[comp + 'i'].copy()
            else:
                raise NotImplementedError(
                    '{:s} is not implemented, as to be RealImag or Complex.')

        # Return
        return outArr
Exemple #27
0
    def Jvec(self, m, v, f=None):
        """
        Jvec computes the sensitivity times a vector

        .. math::
            \mathbf{J} \mathbf{v} = \\frac{d\mathbf{P}}{d\mathbf{F}} \left(
            \\frac{d\mathbf{F}}{d\mathbf{u}} \\frac{d\mathbf{u}}{d\mathbf{m}} +
            \\frac{\partial\mathbf{F}}{\partial\mathbf{m}} \\right) \mathbf{v}

        where

        .. math::
            \mathbf{A} \\frac{d\mathbf{u}}{d\mathbf{m}} +
            \\frac{\partial \mathbf{A}(\mathbf{u}, \mathbf{m})}
            {\partial\mathbf{m}} =
            \\frac{d \mathbf{RHS}}{d \mathbf{m}}
        """

        if f is None:
            f = self.fields(m)

        ftype = self._fieldType + 'Solution'  # the thing we solved for
        self.curModel = m

        # mat to store previous time-step's solution deriv times a vector for
        # each source
        # size: nu x nSrc

        # this is a bit silly

        # if self._fieldType is 'b' or self._fieldType is 'j':
        #     ifields = np.zeros((self.mesh.nF, len(Srcs)))
        # elif self._fieldType is 'e' or self._fieldType is 'h':
        #     ifields = np.zeros((self.mesh.nE, len(Srcs)))

        # for i, src in enumerate(self.survey.srcList):
        dun_dm_v = np.hstack([Utils.mkvc(self.getInitialFieldsDeriv(src, v), 2)
                              for src in self.survey.srcList]
                             ) # can over-write this at each timestep

        # store the field derivs we need to project to calc full deriv
        df_dm_v = Fields_Derivs(self.mesh, self.survey)

        Adiaginv = None

        for tInd, dt in zip(range(self.nT), self.timeSteps):
            # keep factors if dt is the same as previous step b/c A will be the
            # same
            if Adiaginv is not None and (tInd > 0 and dt !=
                                         self.timeSteps[tInd - 1]):
                Adiaginv.clean()
                Adiaginv = None

            if Adiaginv is None:
                A = self.getAdiag(tInd)
                Adiaginv = self.Solver(A, **self.solverOpts)

            Asubdiag = self.getAsubdiag(tInd)

            for i, src in enumerate(self.survey.srcList):

                # here, we are lagging by a timestep, so filling in as we go
                for projField in set([rx.projField for rx in src.rxList]):
                    # Seogi: df_duFun?
                    df_dmFun = getattr(f, '_%sDeriv' % projField, None)
                    # df_dm_v is dense, but we only need the times at
                    # (rx.P.T * ones > 0)
                    # This should be called rx.footprint
                    df_dm_v[src, '{}Deriv'.format(projField), tInd] = df_dmFun(
                        tInd, src, dun_dm_v[:, i], v
                        )

                un_src = f[src, ftype, tInd+1]

                # cell centered on time mesh
                dA_dm_v = self.getAdiagDeriv(tInd, un_src, v)
                # on nodes of time mesh
                dRHS_dm_v = self.getRHSDeriv(tInd+1, src, v)

                dAsubdiag_dm_v = self.getAsubdiagDeriv(tInd, f[src, ftype,
                                                               tInd], v)

                JRHS = dRHS_dm_v - dAsubdiag_dm_v - dA_dm_v

                # step in time and overwrite
                if tInd != len(self.timeSteps+1):
                    dun_dm_v[:, i] = Adiaginv * (JRHS - Asubdiag *
                                                 dun_dm_v[:, i])

        Jv = []
        for src in self.survey.srcList:
            for rx in src.rxList:
                Jv.append(rx.evalDeriv(src, self.mesh, self.timeMesh,
                          Utils.mkvc(df_dm_v[src, '%sDeriv' % rx.projField, :])
                          ))
        Adiaginv.clean()
        # del df_dm_v, dun_dm_v, Asubdiag
        # return Utils.mkvc(Jv)
        return np.hstack(Jv)
Exemple #28
0
 def getUniqueTimes(self):
     time_rx = []
     for src in self.srcList:
         for rx in src.rxList:
             time_rx.append(rx.times)
     self.times = np.unique(np.hstack(time_rx))
Exemple #29
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
Exemple #30
0
def plot_pseudoSection(Tx,Rx,data,z0, stype):
    
    from SimPEG import np, mkvc
    from scipy.interpolate import griddata
    from matplotlib.colors import LogNorm
    import pylab as plt
    import re
    """
        Read list of 2D tx-rx location and plot a speudo-section of apparent
        resistivity.
        
        Assumes flat topo for now...
    
        Input:
        :param d2D, z0
        :switch stype -> Either 'pdp' (pole-dipole) | 'dpdp' (dipole-dipole)
    
        Output:
        :figure scatter plot overlayed on image
        
        Created on Mon December 7th, 2015
    
        @author: dominiquef
    
    """
    #d2D = np.asarray(d2D)
    
    midl = []
    midz = []
    rho = []
    
    for ii in range(len(Tx)):
        # Get distances between each poles
        rC1P1 = np.abs(Tx[ii][0] - Rx[ii][:,0]) 
        rC2P1 = np.abs(Tx[ii][1] - Rx[ii][:,0])
        rC1P2 = np.abs(Tx[ii][1] - Rx[ii][:,1])
        rC2P2 = np.abs(Tx[ii][0] - Rx[ii][:,1])
        rP1P2 = np.abs(Rx[ii][:,1] - Rx[ii][:,0])    
    
        # Compute apparent resistivity
        if re.match(stype,'pdp'):
            rho = np.hstack([rho, data[ii] * 2*np.pi  * rC1P1 * ( rC1P1 + rP1P2 ) / rP1P2] )
            
        elif re.match(stype,'dpdp'):
            rho = np.hstack([rho, data[ii] * 2*np.pi / ( 1/rC1P1 - 1/rC2P1 - 1/rC1P2 + 1/rC2P2 ) ])
    
        Cmid = (Tx[ii][0] + Tx[ii][1])/2
        Pmid = (Rx[ii][:,0] + Rx[ii][:,1])/2
    
        midl = np.hstack([midl, ( Cmid + Pmid )/2 ])
        midz = np.hstack([midz, -np.abs(Cmid-Pmid)/2 + z0 ])
    
   
    # Grid points
    grid_x, grid_z = np.mgrid[np.min(midl):np.max(midl), np.min(midz):np.max(midz)]
    grid_rho = griddata(np.c_[midl,midz], np.log10(abs(1/rho.T)), (grid_x, grid_z), method='linear')
    
    
    #plt.subplot(2,1,2)
    plt.imshow(grid_rho.T, extent = (np.min(midl),np.max(midl),np.min(midz),np.max(midz)), origin='lower', alpha=0.8)
    cbar = plt.colorbar(format = '%.2f',fraction=0.02)
    cmin,cmax = cbar.get_clim()
    ticks = np.linspace(cmin,cmax,3)
    cbar.set_ticks(ticks)
    
    # Plot apparent resistivity
    plt.scatter(midl,midz,s=50,c=np.log10(abs(1/rho.T)))