Beispiel #1
0
 def createInv(self, verbose):
     self.tD = pg.RTrans()
     self.tM = pg.RTrans()
     inv = pg.RInversion(verbose=verbose, dosave=False)
     inv.setTransData(self.tD)
     inv.setTransModel(self.tM)
     return inv
Beispiel #2
0
def chi2(a, b, err, trans=None):
    """Return chi square value."""
    if trans is None:
        trans = pg.RTrans()

    d = (trans(a) - trans(b)) / trans.error(a, err)
    return pg.dot(d, d) / len(d)
Beispiel #3
0
    def inv2D(self,
              nlay,
              lam=100.,
              resL=1.,
              resU=1000.,
              thkL=1.,
              thkU=100.,
              minErr=1.0):
        """2d LCI inversion class."""
        if isinstance(nlay, int):
            modVec = pg.RVector(nlay * 2 - 1, 30.)
            cType = 0  # no reference model
        else:
            modVec = nlay
            cType = 10  # use this as referencemodel
            nlay = (len(modVec) + 1) / 2

        # init forward operator
        self.f2d = self.FOP2d(nlay)

        # transformations
        self.transData = pg.RTrans()
        self.transThk = pg.RTransLogLU(thkL, thkU)
        self.transRes = pg.RTransLogLU(resL, resU)

        for i in range(nlay - 1):
            self.f2d.region(i).setTransModel(self.transThk)

        for i in range(nlay - 1, nlay * 2 - 1):
            self.f2d.region(i).setTransModel(self.transRes)

        # set constraints
        self.f2d.region(0).setConstraintType(cType)
        self.f2d.region(1).setConstraintType(cType)

        # collect data vector
        datvec = pg.RVector(0)

        for i in range(len(self.x)):
            datvec = pg.cat(datvec, self.datavec(i))

        # collect error vector
        if self.ERR is None:
            error = 1.0
        else:
            error = []
            for i in range(len(self.x)):
                err = np.maximum(self.ERR[i][self.activeFreq] * 0.701, minErr)
                error.extend(err)

        # generate starting model by repetition
        model = pg.asvector(np.repeat(modVec, len(self.x)))
        INV = pg.RInversion(datvec, self.f2d, self.transData)
        INV.setAbsoluteError(error)
        INV.setLambda(lam)
        INV.setModel(model)
        INV.setReferenceModel(model)

        return INV
Beispiel #4
0
    def createInv(self, fop, verbose=True, doSave=False):
        """Create default inversion instance for Traveltime inversion."""
        self.tD = pg.RTrans()
        self.tM = pg.RTransLogLU()

        inv = pg.RInversion(verbose, doSave)
        inv.setTransData(self.tD)
        inv.setTransModel(self.tM)
        inv.setForwardOperator(fop)

        return inv
Beispiel #5
0
    def __init__(self, fop, data, error, startmodel, lam=20, beta=10000,
                 maxIter=50, fwmin=0, fwmax=1, fimin=0, fimax=1, famin=0,
                 famax=1, frmin=0, frmax=1):
        LSQRInversion.__init__(self, data, fop, verbose=True, dosave=True)
        self._error = pg.RVector(error)

        # Set data transformations
        self.logtrans = pg.RTransLog()
        self.trans = pg.RTrans()
        self.dcumtrans = pg.RTransCumulative()
        self.dcumtrans.add(self.trans,
                           self.forwardOperator().RST.dataContainer.size())
        self.dcumtrans.add(self.logtrans,
                           self.forwardOperator().ERT.data.size())
        self.setTransData(self.dcumtrans)

        # Set model transformation
        n = self.forwardOperator().cellCount
        self.mcumtrans = pg.TransCumulative()
        self.transforms = []
        phase_limits = [[fwmin, fwmax], [fimin, fimax],
                        [famin, famax], [frmin, frmax]]
        for i, (lower, upper) in enumerate(phase_limits):
            if lower == 0:
                lower = 0.001
            self.transforms.append(pg.RTransLogLU(lower, upper))
            self.mcumtrans.add(self.transforms[i], n)

        self.setTransModel(self.mcumtrans)

        # Set error
        self.setRelativeError(self._error)

        # Set some defaults

        # Set maximum number of iterations (default is 20)
        self.setMaxIter(maxIter)

        # Regularization strength
        self.setLambda(lam)
        self.setDeltaPhiAbortPercent(0.25)

        fop = self.forwardOperator()
        fop.createConstraints()  # Important!
        ones = pg.RVector(fop._I.rows(), 1.0)
        phiVec = pg.cat(ones, startmodel)
        self.setParameterConstraints(fop._G, phiVec, beta)
        self.setModel(startmodel)
Beispiel #6
0
 def createInv(self, nlay, lam=100., errVES=3, verbose=True):
     """Create Marquardt type inversion instance with data transformatio"""
     self.createFOP(nlay)
     self.tMod = pg.RTransLog()
     self.tMRS = pg.RTrans()
     self.tVES = pg.RTransLog()
     self.transData = pg.RTransCumulative()
     self.transData.push_back(self.tMRS, len(self.data))
     self.transData.push_back(self.tVES, len(self.rhoa))
     data = pg.cat(self.data, self.rhoa)
     self.INV = pg.RInversion(data, self.f, self.transData, verbose)
     self.INV.setLambda(lam)
     self.INV.setMarquardtScheme(0.8)
     self.INV.stopAtChi1(False)  # now in MarquardtScheme
     self.INV.setDeltaPhiAbortPercent(0.5)
     #        self.INV.setMaxIter(1)
     error = pg.cat(self.error, self.rhoa * errVES / 100.)
     self.INV.setAbsoluteError(error)
Beispiel #7
0
    def blockLCInversion(self, nlay=2, startModel=None, **kwargs):
        """Laterally constrained (piece-wise 1D) block inversion."""
        data, error, self.nData = pg.RVector(), pg.RVector(), []
        for mrs in self.mrs:
            data = pg.cat(data, mrs.data)
            error = pg.cat(error, mrs.error)
            self.nData.append(len(mrs.data))

        fop = MRSLCI(self.mrs, nlay=nlay)
        fop.region(0).setZWeight(kwargs.pop('zWeight', 0))
        fop.region(0).setConstraintType(kwargs.pop('cType', 1))
        transData, transMod = pg.RTrans(), pg.RTransLog()  # LU(1., 500.)
        if startModel is None:
            startModel = self.block1dInversion(nlay, verbose=False)
        model = kwargs.pop('startvec', np.tile(startModel, len(self.mrs)))
        INV = pg.RInversion(data, fop, transData, transMod, True, False)
        INV.setModel(model)
        INV.setReferenceModel(model)
        INV.setAbsoluteError(error)
        INV.setLambda(kwargs.pop('lam', 100))
        INV.setMaxIter(kwargs.pop('maxIter', 20))
        #        INV.stopAtChi1(False)
        INV.setLambdaFactor(0.9)
        INV.setDeltaPhiAbortPercent(0.1)
        model = INV.run()
        self.WMOD, self.TMOD = [], []
        for par in np.reshape(model, (len(self.mrs), 3 * nlay - 1)):
            thk = par[0:nlay - 1]
            self.WMOD.append(np.hstack((thk, par[nlay - 1:2 * nlay - 1])))
            self.TMOD.append(np.hstack((thk, par[2 * nlay - 1:3 * nlay - 1])))

        ind = np.hstack((0, np.cumsum(self.nData)))
        resp = INV.response()
        misfit = data - resp
        emisfit = misfit / error
        misfit *= 1e9
        self.totalChi2 = INV.chi2()
        self.totalRMS = INV.absrms() * 1e9
        self.RMSvec, self.Chi2vec = [], []
        for i in range(len(self.mrs)):
            self.RMSvec.append(np.sqrt(np.mean(misfit[ind[i]:ind[i + 1]]**2)))
            self.Chi2vec.append(np.mean(emisfit[ind[i]:ind[i + 1]]**2))
Beispiel #8
0
    def test_Trans(self):
        """
        """
        f = pg.RTrans()

        x = pg.RVector(3, 1.0)

        np.testing.assert_array_equal(f(x), x)
        np.testing.assert_array_equal(f.inv(x), x)
        np.testing.assert_array_equal(f.inv(f(x)), x)
        self.assertEqual(f.trans(x=1.0), 1.0)
        self.assertEqual(f(1.0), 1.0)
        self.assertEqual(f.inv(1.0), 1.0)

        f = pg.RTransLin(factor=2., offset=4.)
        np.testing.assert_array_equal(f(x), x*2. + 4.)
        np.testing.assert_array_equal(f.trans(x), x*2. + 4.)
        np.testing.assert_array_equal(f.inv(f(x)), x)
        self.assertEqual(f(1.0), 6.0)
        self.assertEqual(f.trans(1.0), 6.0)
        self.assertEqual(f.inv(6.0), 1.0)
        self.assertEqual(f.invTrans(6.0), 1.0)
Beispiel #9
0
fop.regionManager().region(1).setBackground(True)
fop.createRefinedForwardMesh(refine=True, pRefine=False)

cData = pb.getComplexData(data)
mag = pg.abs(cData)
phi = -pg.phase(cData)

print(pg.norm(mag - data('rhoa')))
print(pg.norm(phi - data('ip') / 1000))

inv = pg.RInversion(pg.cat(mag, phi), fop, verbose=True, dosave=True)

dataTrans = pg.RTransCumulative()
datRe = pg.RTransLog()
datIm = pg.RTrans()
dataTrans.add(datRe, data.size())
dataTrans.add(datIm, data.size())

modRe = pg.RTransLog()
modIm = pg.RTransLog()
modelTrans = pg.RTransCumulative()
modelTrans.add(modRe, fop.regionManager().parameterCount())
modelTrans.add(modIm, fop.regionManager().parameterCount())

inv.setTransData(dataTrans)
inv.setTransModel(modelTrans)
inv.setAbsoluteError(pg.cat(data("err") * mag, mag * phi * 10.01))
inv.setLambda(5)
inv.setMaxIter(5)
Beispiel #10
0
    def fitDebyeModel(self,
                      ePhi=0.001,
                      lam=1e3,
                      lamFactor=0.8,
                      mint=None,
                      maxt=None,
                      nt=None,
                      new=True,
                      showFit=False,
                      cType=1):
        """Fit a (smooth) continuous Debye model (Debye decomposition).

        Parameters
        ----------
        ePhi : float
            absolute error of phase angle
        lam : float
            regularization parameter
        lamFactor : float
            regularization factor for subsequent iterations
        mint/maxt : float
            minimum/maximum tau values to use (else automatically from f)
        nt : int
            number of tau values (default number of frequencies * 2)
        new : bool
            new implementation (experimental)
        showFit : bool
            show fit
        cType : int
            constraint type (1/2=smoothness 1st/2nd order, 0=minimum norm)
        """
        nf = len(self.f)
        if mint is None:
            mint = .1 / max(self.f)
        if maxt is None:
            maxt = .5 / min(self.f)
        if nt is None:
            nt = nf * 2
        # discretize tau, setup DD and perform DD inversion
        self.tau = np.logspace(log10(mint), log10(maxt), nt)
        phi = self.phi
        tLin, tLog, tM = pg.RTrans(), pg.RTransLog(), pg.RTransLog()
        # pg.RTransLogLU(0., 1.)
        if new:
            reNorm, imNorm = self.zNorm()
            fDD = DebyeComplex(self.f, self.tau)
            Znorm = pg.cat(reNorm, imNorm)
            IDD = pg.RInversion(Znorm, fDD, tLog, tM, False)
            IDD.setAbsoluteError(max(Znorm) * 0.003 + 0.01)
        else:
            fDD = DebyePhi(self.f, self.tau)
            IDD = pg.RInversion(phi, fDD, tLin, tM, True)
            IDD.setAbsoluteError(ePhi)  # 1 mrad

        fDD.regionManager().setConstraintType(cType)
        IDD.stopAtChi1(False)
        startModel = pg.RVector(nt, 0.01)
        IDD.setModel(startModel)
        IDD.setLambda(lam)
        IDD.setLambdaFactor(lamFactor)
        self.mDD = IDD.run()
        IDD.echoStatus()
        if new:
            resp = np.array(IDD.response())
            respRe = resp[:nf]
            respIm = resp[nf:]
            respC = ((1 - respRe) + respIm * 1j) * max(self.amp)
            self.phiDD = np.angle(respC)
            self.ampDD = np.abs(respC)
            if showFit:
                fig, ax = self.showData(znorm=True, nrows=3)
                self.fig['DebyeFit'] = fig
                ax[0].plot(self.f, respRe, 'r-')
                ax[1].plot(self.f, respIm, 'r-')
                ax[2].semilogx(self.tau, self.mDD, 'r-')
                ax[2].set_xlim(max(self.tau), min(self.tau))
                ax[2].set_ylim(0., max(self.mDD))
                ax[2].grid(True)
                ax[2].set_xlabel(r'$\tau$ (s)')
                ax[2].set_ylabel('$m$ (-)')
        else:
            self.phiDD = IDD.response()
            if showFit:
                fig, ax = self.showData(nrows=3)
                self.fig['DebyeSpectrum'] = fig
                ax[2].semilogx(self.tau, self.mDD, 'r-')
Beispiel #11
0
freq = pg.RVector(nf, 110.)
for i in range(nf - 1):
    freq[i + 1] = freq[i] * 2.

fEM = pg.FDEM1dModelling(nlay, freq, coilspacing)
dataEM = fEM(model)
for i in range(len(dataEM)):
    dataEM[i] += np.random.randn(1)[0] * noiseEM

###############################################################################
# We define model transformations: logarithms and log with upper+lower bounds

transRhoa = pg.RTransLog()
transThk = pg.RTransLog()
transRes = pg.RTransLogLU(1., 1000.)
transEM = pg.RTrans()
fEM.region(0).setTransModel(transThk)
fEM.region(1).setTransModel(transRes)

###############################################################################
# We set up the independent EM inversion and run the model.

invEM = pg.RInversion(dataEM, fEM, transEM, verbose)
modelEM = pg.RVector(nlay * 2 - 1, 50.)
invEM.setModel(modelEM)
invEM.setAbsoluteError(noiseEM)
invEM.setLambda(lamEM)
invEM.setMarquardtScheme(0.9)
modelEM = invEM.run()
respEM = invEM.response()
Beispiel #12
0
# EM forward operator and synthetic data
coilspacing = 50.
nf = 10
freq = g.RVector(nf, 110.)
for i in range(nf - 1):
    freq[i + 1] = freq[i] * 2.
fEM = g.FDEM1dModelling(nlay, freq, coilspacing)
dataEM = fEM(model)
for i in range(len(dataEM)):
    dataEM[i] += P.randn(1)[0] * noiseEM

# model transformations
transRhoa = g.RTransLog()
transThk = g.RTransLog()
transRes = g.RTransLogLU(1., 1000.)
transEM = g.RTrans()
fEM.region(0).setTransModel(transThk)
fEM.region(1).setTransModel(transRes)

# independent EM inversion
invEM = g.RInversion(dataEM, fEM, transEM, verbose)
modelEM = g.RVector(nlay * 2 - 1, 50.)
invEM.setModel(modelEM)
invEM.setAbsoluteError(noiseEM)
invEM.setLambda(lamEM)
invEM.setMarquardtScheme(0.9)
modelEM = invEM.run()
respEM = invEM.response()

# DC forward operator and synthetic data
ab2 = g.RVector(20, 3.)
Beispiel #13
0
    def invBlock(self,
                 xpos=0,
                 nlay=2,
                 noise=1.0,
                 stmod=30.,
                 lam=100.,
                 lBound=0.,
                 uBound=0.,
                 verbose=False):
        """Create and return Gimli inversion instance for block inversion.

        Parameters
        ----------
        xpos : array
            position vector

        nLay : int
            Number of layers of the model to be determined OR
            vector of layer numbers OR forward operator

        noise : float
            Absolute data err in percent

        stmod : float or pg.RVector
            Starting model

        lam : float
            Global regularization parameter lambda.

        lBound : float
            Lower boundary for the model

        uBound : float
            Upper boundary for the model. 0 means no upper booundary

        verbose : bool
            Be verbose
        """
        self.transThk = pg.RTransLog()
        self.transRes = pg.RTransLogLU(lBound, uBound)
        self.transData = pg.RTrans()

        # EM forward operator
        if isinstance(nlay, pg.FDEM1dModelling):
            self.fop = nlay
        else:
            self.fop = self.FOP(nlay)

        data = self.datavec(xpos)

        self.fop.region(0).setTransModel(self.transThk)
        self.fop.region(1).setTransModel(self.transRes)

        if isinstance(noise, float):
            noiseVec = pg.RVector(len(data), noise)
        else:
            noiseVec = pg.asvector(noise)

        # independent EM inversion
        self.inv = pg.RInversion(data, self.fop, self.transData, verbose)
        if isinstance(stmod, float):  # real model given
            model = pg.RVector(nlay * 2 - 1, stmod)
            model[0] = 2.
        else:
            if len(stmod) == nlay * 2 - 1:
                model = pg.asvector(stmod)
            else:
                model = pg.RVector(nlay * 2 - 1, 30.)

        self.inv.setAbsoluteError(noiseVec)
        self.inv.setLambda(lam)
        self.inv.setMarquardtScheme(0.8)
        self.inv.setDeltaPhiAbortPercent(0.5)
        self.inv.setModel(model)
        self.inv.setReferenceModel(model)
        return self.inv