示例#1
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
示例#2
0
def qtblockmodelling(mydir,
                     nlay,
                     startvec=None,
                     lowerbound=None,
                     upperbound=None):
    """Loads data from dir, creates forward operator (old style)

    Parameters
    ----------
    mydir : string
        directory to load the files (kernel, data) from
    nlay : int
        number of layers
    startvec : array
        starting vector
    lowerbound : tuple/list of 3 values
        lower bound for thickness, water content and relaxation time
    upperbound : tuple/list of 3 values
        upper bound for thickness, water content and relaxation time

    Returns
    -------
    t : array
        time vector
    datvec : array
        data cube in a vector
    f : pygimli modelling class
        forward operator

    Examples
    --------

    t,datvec,f = qtblockmodelling(mydir,nlay,startvec=(10,0.3,0.2),
                                  lowerbound=(0.1,0,0.02),
                                  upperbound(100.,0.45,,0.5))
    """
    KR, KI, zvec, t, datvec = loadmrsproject(mydir)
    if startvec is None:
        startvec = [10., 0.3, 0.2]
    if lowerbound is None:
        lowerbound = [0.1, 0.0, 0.02]
    if upperbound is None:
        upperbound = [100., 0.45, 0.5]
    # modelling operator
    f = MRS1dBlockQTModelling(nlay, KR, KI, zvec, t)  # A[0])
    f.region(0).setStartValue(startvec[0])
    f.region(1).setStartValue(startvec[1])
    f.region(2).setStartValue(startvec[2])
    # Model transformations
    f.transTH = pg.RTransLogLU(lowerbound[0], upperbound[0])
    f.transWC = pg.RTransLogLU(lowerbound[1], upperbound[1])
    f.transT2 = pg.RTransLogLU(lowerbound[2], upperbound[2])
    f.region(0).setTransModel(f.transTH)
    f.region(1).setTransModel(f.transWC)
    f.region(2).setTransModel(f.transT2)
    return t, datvec, f
示例#3
0
    def createInv(self, fop, verbose=True, dosave=False):
        """Create inversion instance."""
        self.tD = pg.RTransLog()
        self.tM = pg.RTransLogLU()

        inv = pg.RInversion(verbose, dosave)
        inv.setTransData(self.tD)
        inv.setTransModel(self.tM)
        inv.setForwardOperator(fop)
        return inv
示例#4
0
 def createFOP(self, nlay, verbose=False):
     """creates forward operator for given number of layers"""
     self.nlay = nlay
     self.f = MRSVESBlockModelling(nlay, self.K, self.z, self.t, self.ab2,
                                   self.mn2, verbose)
     self.trans = []  # save in class to keep them alive
     for i in range(4):  # thk, cw, T2*, res
         self.f.region(i).setStartValue(self.startval[i])
         self.trans.append(
             pg.RTransLogLU(self.lowerBound[i], self.upperBound[i]))
         self.f.region(i).setTransModel(self.trans[-1])
示例#5
0
    def createInv(self, fop, verbose=True, doSave=False):
        """Create default inversion instance for Traveltime inversion.

        base api
        (typically done by run)
        """
        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
示例#6
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)
示例#7
0
mn2 = ab2 / 3.  # MN/2 distance (potential electrodes)
###############################################################################
# initialize the forward modelling operator
f = pg.DC1dModelling(nlay, ab2, mn2)
###############################################################################
# other ways are by specifying a Data Container or am/an/bm/bn distances
synres = [100., 500., 20., 800.]  # synthetic resistivity
synthk = [0.5, 3.5, 6.]  # synthetic thickness (nlay-th layer is infinite)
###############################################################################
# the forward operator can be called by f.response(model) or simply f(model)
rhoa = f(synthk + synres)
rhoa = rhoa * (pg.randn(len(rhoa)) * errPerc / 100. + 1.)
###############################################################################
# create some transformations used for inversion
transThk = pg.RTransLog()  # log-transform ensures thk>0
transRho = pg.RTransLogLU(1, 1000)  # lower and upper bound
transRhoa = pg.RTransLog()  # log transformation for data
###############################################################################
# set model transformation for thickness and resistivity
f.region(0).setTransModel(transThk)  # 0=thickness
f.region(1).setTransModel(transRho)  # 1=resistivity
###############################################################################
# generate start model values from median app. resistivity & spread
paraDepth = max(ab2) / 3.  # rule-of-thumb for Wenner/Schlumberger
f.region(0).setStartValue(paraDepth / nlay / 2)
f.region(1).setStartValue(np.median(rhoa))
###############################################################################
# set up inversion
inv = pg.RInversion(rhoa, f, transRhoa, True)  # data vector, fop, verbose
# could also be set by inv.setTransData(transRhoa)
###############################################################################
示例#8
0
import pygimli as g
import pylab as P
from pygimli.utils.base import draw1dmodel

nlay = 4
lam = 200.
errPerc = 3.

abmnr = g.RMatrix()
g.loadMatrixCol(abmnr, "sond1-100.ves")
ab2 = abmnr[0]
mn2 = abmnr[1]
rhoa = abmnr[2]

transRho = g.RTransLogLU(1., 1000.)
transThk = g.RTransLog()
transRhoa = g.RTransLog()

f = g.DC1dModelling(nlay, ab2, mn2)
f.region(0).setTransModel(transThk)
f.region(1).setTransModel(transRho)

paraDepth = max(ab2) / 3
f.region(0).setStartValue(max(ab2) / 3. / nlay / 2.)
f.region(1).setStartValue(P.median(rhoa))

model = f.createStartVector()
model[nlay] *= 1.5

inv = g.RInversion(rhoa, f, True)
示例#9
0
def main():
    # read config file
    conf_file = "inv.conf"
    with open(conf_file, "r") as fd:
        conf = json.load(fd)

    # res = pb.Resistivity("input.dat")
    # res.invert()
    # np.savetxt('resistivity.vector', res.resistivity)
    # return

    # load data file
    data = pg.DataContainerERT("input.dat")

    # remove invalid data
    oldsize = data.size()
    data.removeInvalid()
    newsize = data.size()
    if newsize < oldsize:
        print('Removed ' + str(oldsize - newsize) + ' values.')
    if not data.allNonZero('rhoa'):
        print("No or partial rhoa values.")
        return

    # check, compute error
    if data.allNonZero('err'):
        error = data('err')
    else:
        print("estimate data error")
        error = conf["relativeError"] + conf["absoluteError"] / data('rhoa')

    # create FOP
    fop = pg.DCSRMultiElectrodeModelling(verbose=conf["verbose"])
    fop.setThreadCount(psutil.cpu_count(logical=False))
    fop.setData(data)

    # create Inv
    inv = pg.RInversion(verbose=conf["verbose"], dosave=False)
    # variables tD, tM are needed to prevent destruct objects
    tD = pg.RTransLog()
    tM = pg.RTransLogLU()
    inv.setTransData(tD)
    inv.setTransModel(tM)
    inv.setForwardOperator(fop)

    # mesh
    if conf["meshFile"] == "":
        depth = conf["depth"]
        if depth is None:
            depth = pg.DCParaDepth(data)

        poly = pg.meshtools.createParaMeshPLC(
            data.sensorPositions(),
            paraDepth=depth,
            paraDX=conf["paraDX"],
            paraMaxCellSize=conf["maxCellArea"],
            paraBoundary=2,
            boundary=2)

        if conf["verbose"]:
            print("creating mesh...")
        mesh = pg.meshtools.createMesh(poly,
                                       quality=conf["quality"],
                                       smooth=(1, 10))
    else:
        mesh = pg.Mesh(pg.load(conf["meshFile"]))

    mesh.createNeighbourInfos()

    if conf["verbose"]:
        print(mesh)

    sys.stdout.flush()  # flush before multithreading
    fop.setMesh(mesh)
    fop.regionManager().setConstraintType(1)

    if not conf["omitBackground"]:
        if fop.regionManager().regionCount() > 1:
            fop.regionManager().region(1).setBackground(True)

    if conf["meshFile"] == "":
        fop.createRefinedForwardMesh(True, False)
    else:
        fop.createRefinedForwardMesh(conf["refineMesh"], conf["refineP2"])

    paraDomain = fop.regionManager().paraDomain()
    inv.setForwardOperator(fop)  # necessary?

    # inversion parameters
    inv.setData(data('rhoa'))
    inv.setRelativeError(error)
    fop.regionManager().setZWeight(conf['zWeight'])
    inv.setLambda(conf['lam'])
    inv.setMaxIter(conf['maxIter'])
    inv.setRobustData(conf['robustData'])
    inv.setBlockyModel(conf['blockyModel'])
    inv.setRecalcJacobian(conf['recalcJacobian'])

    pc = fop.regionManager().parameterCount()
    startModel = pg.RVector(pc, pg.median(data('rhoa')))

    inv.setModel(startModel)

    # Run the inversion
    sys.stdout.flush()  # flush before multithreading
    model = inv.run()
    resistivity = model(paraDomain.cellMarkers())
    np.savetxt('resistivity.vector', resistivity)
    print("Done.")
示例#10
0
    # Reflect the fix value setting here!!!!
    fop.createRefinedForwardMesh(refine=False, pRefine=False)

    # Connect all regions
    for i in range(2, fop.regionManager().regionCount()):
        for j in range(i + 1, fop.regionManager().regionCount()):
            fop.regionManager().setInterRegionConstraint(i, j, 1.0)

    startModel = pg.RVector(fop.regionManager().parameterCount(), 1e-3)

    fop.setStartModel(startModel)

    inv = pg.RInversion(rhoaR.flatten(), fop, verbose=1, dosave=0)

    tD = pg.RTransLog()
    tM = pg.RTransLogLU(1e-9, 1e-2)
    inv.setTransData(tD)
    inv.setTransModel(tM)

    inv.setRelativeError(err.flatten())
    inv.setMaxIter(50)
    inv.setLineSearch(True)
    inv.setLambda(1000)

    outPath = "permModel_h-" + str(paraRefine)
    if not os.path.exists(outPath):
        os.mkdir(outPath)

    paraMesh.save(outPath + '/paraMesh')
    fop.mesh().save(outPath + "/fopMesh")
    fop.regionManager().paraDomain().save(outPath + '/paraDomain')
示例#11
0
nf = 10
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()
示例#12
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