Exemple #1
0
    def invert(self,
               data=None,
               useGradient=True,
               vTop=500,
               vBottom=5000,
               secNodes=2,
               **kwargs):
        """Invert data.

        Parameters
        ----------
        data : pg.DataContainer()
            Data container with at least SensorIndieces 's g' and
            data values 't' (traveltime in ms) and 'err' (absolute error in ms)
        useGradient: bool [True]
            Use a gradient like starting model suited for standard flat
            earth cases. [Default]
            For cross tomography geometry you should set this to False for a
            non gradient startind model.
        vTop: float
            Top velocity for gradient stating model.
        vBottom: float
            Bottom velocity for gradient stating model.
        secNodes: int [2]
            Amount of secondary nodes used for ensure accuracy of the forward
            operator.

        Keyword Arguments
        -----------------
        ** kwargs:
            Inversion related arguments:
            See :py:mod:`pygimli.frameworks.MeshMethodManager.invert`
        """
        mesh = kwargs.pop('mesh', None)

        self.secNodes = secNodes

        if 'limits' in kwargs:
            if kwargs['limits'][0] > 1:
                tmp = kwargs['limits'][0]
                kwargs['limits'][0] = 1.0 / kwargs['limits'][1]
                kwargs['limits'][1] = 1.0 / tmp
                pg.verbose('Switching velocity limits to slowness limits.',
                           kwargs['limits'])

        if useGradient:
            self.fop._useGradient = [vTop, vBottom]
        else:
            self.fop._useGradient = None

        slowness = super().invert(data, mesh, **kwargs)
        velocity = 1.0 / slowness
        self.fw.model = velocity
        return velocity
Exemple #2
0
    def createRefinedFwdMesh(self, mesh):
        """Refine the current mesh for higher accuracy.

        This is called automatic when accesing self.mesh() so it ensures any
        effect of changing region properties (background, single).
        """
        pg.info("Creating refined mesh (secnodes: {0}) to "
                "solve forward task.".format(self._refineSecNodes))
        m = mesh.createMeshWithSecondaryNodes(self._refineSecNodes)
        pg.verbose(m)
        return m
Exemple #3
0
    def createForwardOperator(self, **kwargs):
        """Create and choose forward operator. """
        verbose = kwargs.pop('verbose', False)
        self.useBert = kwargs.pop('useBert', self.useBert)
        self.sr = kwargs.pop('sr', self.sr)
        if self.useBert:
            pg.verbose('Create ERTModelling FOP')
            fop = ERTModelling(sr=self.sr, verbose=verbose)
        else:
            pg.verbose('Create ERTModellingReference FOP')
            fop = ERTModellingReference(**kwargs)

        return fop
Exemple #4
0
    def createRefinedFwdMesh(self, mesh):
        """Refine the current mesh for higher accuracy.

        This is called automatic when accessing self.mesh() so it ensures any
        effect of changing region properties (background, single).
        """
        if self._refineP2 == True:
            pg.info("Creating refined mesh (P2) to solve forward task.")
            m = mesh.createP2()
        else:
            pg.info("Creating refined mesh (H2) to solve forward task.")
            m = mesh.createH2()
        pg.verbose(m)
        return m
Exemple #5
0
    def startModel(self):
        """ Gives the current default starting model.

        Returns the current default starting model or
        call fop.createStartmodel() if non is defined.
        """
        if self._startModel is None:
            sm = self.fop.regionManager().createStartModel()
            if len(sm) > 0 and max(abs(np.atleast_1d(sm))) > 0.0:
                self._startModel = sm
                pg.info("Created startmodel from region infos:", sm)
            else:
                pg.verbose("No region infos for startmodel")

        if self._startModel is None:
            sm = self.fop.createStartModel(self.dataVals)
            pg.info("Created startmodel from forward operator:", sm)
            self._startModel = sm
        return self._startModel
Exemple #6
0
    def createFwdMesh_(self):
        """"""
        pg.info("Creating forward mesh from region infos.")
        m = pg.Mesh(self.regionManager().mesh())

        regionIds = self.regionManager().regionIdxs()
        for iId in regionIds:
            pg.verbose("\tRegion: {0}, Parameter: {1}, PD: {2},"
                       " Single: {3}, Background: {4}, Fixed: {5}"
                .format(iId,
                        self.regionManager().region(iId).parameterCount(),
                        self.regionManager().region(iId).isInParaDomain(),
                        self.regionManager().region(iId).isSingle(),
                        self.regionManager().region(iId).isBackground(),
                        self.regionManager().region(iId).fixValue(),
                        ))

        m = self.createRefinedFwdMesh(m)
        self.setMeshPost(m)
        self._regionChanged = False
        super(Modelling, self).setMesh(m, ignoreRegionManager=True)
Exemple #7
0
    def setRegionProperties(self, regionNr, **kwargs):
        """ Set region properties. regionNr can be wildcard '*' for all regions.

            startModel=None, limits=None, trans=None,
            cType=None, zWeight=None, modelControl=None,
            background=None, single=None, fix=None

        Parameters
        ----------
        """
        if regionNr == '*':
            for regionNr in self.regionManager().regionIdxs():
                self.setRegionProperties(regionNr, **kwargs)
            return

        pg.verbose('Set property for region: {0}: {1}'.format(
            regionNr, kwargs))
        if regionNr not in self._regionProperties:
            self._regionProperties[regionNr] = {
                'startModel': None,
                'modelControl': 1.0,
                'zWeight': 1.0,
                'cType': None,  # use RM defaults
                'limits': [0, 0],
                'trans': 'Log',  # use RM defauts
                'background': None,
                'single': None,
                'fix': None,
            }

        for key in list(kwargs.keys()):
            val = kwargs.pop(key)
            if val is not None:
                if self._regionProperties[regionNr][key] != val:
                    self._regionsNeedUpdate = True
                    self._regionProperties[regionNr][key] = val

        if len(kwargs) > 0:
            pg.warn('Unhandled region properties:', kwargs)
Exemple #8
0
    def simulate(self,
                 mesh,
                 scheme,
                 slowness=None,
                 vel=None,
                 secNodes=2,
                 noiseLevel=0.0,
                 noiseAbs=0.0,
                 **kwargs):
        """Simulate Traveltime measurements.

        Perform the forward task for a given mesh, a slowness distribution (per
        cell) and return data (traveltime) for a measurement scheme.

        Parameters
        ----------
        mesh : :gimliapi:`GIMLI::Mesh`
            Mesh to calculate for or use the last known mesh.
        scheme: :gimliapi:`GIMLI::DataContainer`
            Data measurement scheme needs 's' for shot and 'g' for geophone
            data token.
        slowness : array(mesh.cellCount()) | array(N, mesh.cellCount())
            Slowness distribution for the given mesh cells can be:

            * a single array of len mesh.cellCount()
            * a matrix of N slowness distributions of len mesh.cellCount()
            * a res map as [[marker0, res0], [marker1, res1], ...]
        vel : array(mesh.cellCount()) | array(N, mesh.cellCount())
            Velocity distribution for the given mesh cells.
            Will overwrite given slowness.
        secNodes: int [2]
            Number of refinement nodes to increase accuracy of the forward
            calculation.
        noiseLevel: float [0.0]
            Add relative noise to the simulated data. noiseLevel*100 in %
        noiseAbs: float [0.0]
            Add absolute noise to the simulated data in ms.

        Keyword Arguments
        -----------------
        returnArray: [False]
            Return only the calculated times.
        verbose: [self.verbose]
            Overwrite verbose level.
        **kwargs
            Additional kwargs ...

        Returns
        -------
        t : array(N, data.size()) | DataContainer
            The resulting simulated travel time values.
            Either one column array or matrix in case of slowness matrix.
        """
        verbose = kwargs.pop('verbose', self.verbose)

        fop = self.fop
        fop.data = scheme
        fop.verbose = verbose

        if mesh is not None:
            self.applyMesh(mesh, secNodes=secNodes, ignoreRegionManager=True)

        if vel is not None:
            slowness = 1 / vel

        if slowness is None:
            pg.critical(
                "Need some slowness or velocity distribution for simulation.")

        if len(slowness) == self.fop.mesh().cellCount():
            t = fop.response(slowness)
        else:
            print(self.fop.mesh())
            print("slowness: ", slowness)
            pg.critical("Simulate called with wrong slowness array.")

        ret = pg.DataContainer(scheme)
        ret.set('t', t)

        if noiseLevel > 0 or noiseAbs > 0:
            if not ret.allNonZero('err'):
                ret.set('t', t)
                err = noiseAbs + t * noiseLevel
                ret.set('err', err)

            pg.verbose(
                "Absolute data error estimates (min:max) {0}:{1}".format(
                    min(ret('err')), max(ret('err'))))

            np.random.seed(0)

            t += np.random.randn(ret.size()) * ret('err')
            ret.set('t', t)

        if kwargs.pop('returnArray', False) is True:
            return t

        return ret
Exemple #9
0
def readSIP256file(resfile, verbose=False):
    """Read SIP256 file (RES format) - mostly used for 2d SIP by pybert.sip.

    Read SIP256 file (RES format) - mostly used for 2d SIP by pybert.sip.

    Parameters
    ----------
    filename: str
        *.RES file (SIP256 raw output file)
    verbose: bool
        do some output [False]

    Returns
    -------
        header - dictionary of measuring setup
        DATA - data AB-list of MN-list of matrices with f, amp, phi, dAmp, dPhi
        AB - list of current injection
        RU - list of remote units

    Examples
    --------
        header, DATA, AB, RU = readSIP256file('myfile.res', True)
    """
    activeBlock = ''
    header = {}
    LINE = []
    dataAct = False

    with codecs.open(resfile, 'r', encoding='iso-8859-15',
                     errors='replace') as fi:
        content = fi.readlines()

    for line in content:
        if dataAct:
            LINE.append(line)
        elif len(line):
            if line[0] == '[':
                token = line[1:line.rfind(']')].replace(' ', '_')
                # handle early 256D software bug
                if 'FrequencyParameterBegin' in token:
                    token = token.replace('FrequencyParameterBegin',
                                          'Begin_FrequencyParameter')
                if 'FrequencyParameterEnd' in token:
                    token = token.replace('FrequencyParameterEnd',
                                          'End_FrequencyParameter')

                if token.replace(' ', '_') == 'Messdaten_SIP256':
                    dataAct = True
                elif 'Messdaten' in token:
                    # res format changed into SIP256D .. so we are a
                    # little bit more flexible with this.
                    dataAct = True
                elif token[:3] == 'End':
                    header[activeBlock] = np.array(header[activeBlock])
                    activeBlock = ''
                elif token[:5] == 'Begin':
                    activeBlock = token[6:]
                    header[activeBlock] = []
                else:
                    value = line[line.rfind(']') + 1:]
                    try:  # direct line information
                        if '.' in value:
                            num = float(value)
                        else:
                            try:
                                num = int(value)
                            except:
                                num = 0
                                pass
                        header[token] = num
                    except BaseException as e:
                        # maybe beginning or end of a block
                        print(e)
            else:
                if activeBlock:
                    nums = np.array(line.split(), dtype=float)
                    header[activeBlock].append(nums)

    DATA, dReading, dFreq, AB, RU, ru = [], [], [], [], [], []
    tMeas = []
    for i, line in enumerate(LINE):
        # print(i, line)
        line = line.replace(' nc ', ' 0 ')  # no calibration should 0
        line = line.replace(' c ', ' 1 ')  # calibration should 1
        # sline = line.split()
        sline = line.rstrip('\r\n').split()
        if line.find('Reading') == 0:
            rdno = int(sline[1])
            if rdno > 0:
                AB.append((int(sline[4]), int(sline[6])))
            if ru:
                RU.append(ru)
                ru = []
            if rdno > 1 and dReading:
                dReading.append(np.array(dFreq))
                DATA.append(dReading)
                pg.verbose('Reading {0}:{1} RUs'.format(
                    rdno - 1, len(dReading)))
                dReading, dFreq = [], []
        elif line.find('Remote Unit') == 0:
            ru.append(int(sline[2]))
            if dFreq:
                dReading.append(np.array(dFreq))
                dFreq = []
        elif line.find('Freq') >= 0:
            pass
        elif len(sline) > 1 and rdno > 0:  # some data present
            # search for two numbers (with .) without a space inbetween
            # variant 1: do it for every part
            for i, ss in enumerate(sline):
                if re.search('\.20[01][0-9]', ss) is None:  # no date
                    fd = re.search('\.[0-9-]*\.', ss)
                    if fd:
                        if '-' in ss[1:]:
                            bpos = ss[1:].find('-') + 1
                        else:
                            bpos = fd.start() + 4

                        # print(ss[:bpos], ss[bpos:])
                        sline.insert(i, ss[:bpos])
                        sline[i + 1] = ss[bpos:]
                        # print(sline)
                    fd = re.search('NaN[0-9-]*\.', ss)
                    if fd:
                        if '-' in ss[1:]:
                            bpos = ss.find('-')
                        else:
                            bpos = fd.start() + 3

                        # print(ss[:bpos], ss[bpos:])
                        sline.insert(i, ss[:bpos])
                        sline[i + 1] = ss[bpos:]
                        # print(sline)
            # variant 2: do it on whole line
            # cdate = re.search('\.20[01][0-9]', line)
            # if cdate:
            #     n2000 = cdate.start()
            # else:
            #     n2000 = len(line)

            # print(sline)
            # concnums = re.search('\.[0-9-]*\.', line[:n2000])
            # while concnums:
            #     bpos = concnums.span()[0] + 4
            #     line = line[:bpos] + ' ' + line[bpos:]
            #     n2000 += 1
            #     concnums = re.search('\.[0-9-]*\.', line[:n2000])
            #     sline = line.rstrip('\r\n').split()
            #     print(sline)

            # if re.search('[0-9]-', line[:85]):  # missing whitespace before -
            #     sline = re.sub('[0-9]-', '5 -', line).split()
            # not a good idea for dates

            for c in range(7):  # this is expensive .. do we really need this?
                if len(sline[c]) > 15:  # too long line / missing space
                    if c == 0:
                        part1 = sline[c][:-15]
                        part2 = sline[c][-15:]  # [10:]
                    else:
                        part1 = sline[c][:-10]
                        part2 = sline[c][-10:]  # [11:]
                    sline = sline[:c] + [part1] + [part2] + sline[c + 1:]

                if sline[c].find('c') >= 0:
                    sline[c] = '1.0'
            #Frequency /Hz       RA/Ohmm    PA/�      ERA/%     EPA/�     Cal?     IA/mA     K.-F./m    Gains  Time/h:m:s    Date/d.m.y
            #20000.00000000        0.4609  -6.72598   0.02234   0.01280    1      20.067        1.00      0     11:08:02     21/02/2019
            try:
                dFreq.append(
                    np.array(sline[:8] + [toTime(sline[-2], sline[-1])],
                             dtype=float))
            except:
                # dFreq.append(np.array(sline[:8], dtype=float))
                print(i, line, sline)
                raise ImportError()

    dReading.append(np.array(dFreq))
    DATA.append(dReading)
    pg.verbose('Reading {0}:{1} RUs'.format(rdno, len(dReading)))
    return header, DATA, AB, RU
Exemple #10
0
def testVerboseDecorator2():
    pg.verbose(
        'testVerboseDecorator2 should be only seen even if verbose is set to true'
    )
Exemple #11
0
def testVerboseDecorator1():
    pg.verbose(
        'testVerboseDecorator1 should be seen even if verbose is set to false')
Exemple #12
0
import pygimli as pg

#log = logging.getLogger('pyGIMLi')

#logging.basicConfig(level=logging.DEBUG,
#format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
#datefmt='%m/%d/%Y %H:%M:%S',
##filename='example.log'
#)
pg.version()

# test pygimli log
pg.info("Start numeric log test." + str(pg.log(pg.Vector(1, 1.))))
pg.setVerbose(True)
pg.verbose("some verbose notes")
pg.warn("Start warning test.")


def testTraceback1():
    def testTraceback2():
        pg.error("Start error test.: int", 1, " vec", pg.Vector(2))

    testTraceback2()


testTraceback1()


@pg.v
def testVerboseDecorator1():
    pg.verbose(
Exemple #13
0
    def setRegionProperties(self, regionNr, **kwargs):
        """ Set region properties. regionNr can be '*' for all regions.

            startModel=None, limits=None, trans=None,
            cType=None, zWeight=None, modelControl=None,
            background=None, fix=None, single=None,
            correlationLengths=None, dip=None, strike=None

        Parameters
        ----------
        regionNr : int, [ints], '*'
            Region number, list of numbers, or wildcard "*" for all.
        startModel : float
            starting model value
        limits : [float, float]
            lower and upper limit for value using a barrier transform
        trans : str
            transformation for model barrier: "log", "cot", "lin"
        cType : int
            constraint (regularization) type
        zWeight : float
            relative weight for vertical boundaries
        background : bool
            exclude region from inversion completely (prolongation)
        fix : float
            exclude region from inversion completely (fix to value)
        single : bool
            reduce region to one unknown
        correlationLengths : [floats]
            correlation lengths for geostatistical inversion (x', y', z')
        dip : float [0]
            angle between x and x' (first correlation length)
        strike : float [0]
            angle between y and y' (second correlation length)
        """
        if regionNr == '*':
            for regionNr in self.regionManager().regionIdxs():
                self.setRegionProperties(regionNr, **kwargs)
            return
        elif isinstance(regionNr, (list, tuple)):
            for r in regionNr:
                self.setRegionProperties(r, **kwargs)
            return

        pg.verbose('Set property for region: {0}: {1}'.format(
            regionNr, kwargs))
        if regionNr not in self._regionProperties:
            self._regionProperties[regionNr] = {
                'startModel': None,
                'modelControl': 1.0,
                'zWeight': 1.0,
                'cType': None,  # RM defaults
                'limits': [0, 0],
                'trans': 'Log',  # RM defauts
                'background': None,
                'single': None,
                'fix': None,
                'correlationLengths': None,
                'dip': None,
                'strike': None,
            }

        for key in list(kwargs.keys()):
            val = kwargs.pop(key)
            if val is not None:
                if self._regionProperties[regionNr][key] != val:
                    self._regionsNeedUpdate = True
                    self._regionProperties[regionNr][key] = val

        if len(kwargs) > 0:
            pg.warn('Unhandled region properties:', kwargs)
Exemple #14
0
def testVerboseDecorator2():
    pg.verbose('testVerboseDecorator2 should be seen even if verbose is true')