def drawModel(ax=None, mesh=None, data=None, **kwargs): """ Draw the mesh with given data. Parameters ---------- ax: pyvista.Plotter [None] Pyvista's basic Plotter to add the mesh to. mesh: pg.Mesh The Mesh to plot. data: iterable Data that should be displayed with the mesh. Returns ------- ax: pyvista.Plotter [optional] The plotter """ if all(v is None for v in [ax, mesh, data]): pg.critical("At least mesh or data should not be None") return None if data is not None or len(mesh.dataMap()) != 0: kwargs['style'] = 'surface' kwargs['color'] = None mesh = pgMesh2pvMesh(mesh, data, kwargs.pop('label', None)) if 'cmap' not in kwargs: kwargs['cmap'] = 'viridis' return drawMesh(ax, mesh, **kwargs)
def _concat(v, vBound): if (not pg.isArray(vBound)): pg.critical("please give bound array") v = np.append(-np.array(vBound)[::-1] + v[0], v) v = np.append(v, v[-1] + np.array(vBound)) return v
def appendBoundary(mesh, **kwargs): """ Append Boundary to a given mesh. Syntactic sugar for :py:mod:`pygimli.meshtools.appendTriangleBoundary` and :py:mod:`pygimli.meshtools.appendTetrahedronBoundary`. Parameters ---------- mesh: :gimliapi:`GIMLI::Mesh` "2d or 3d Mesh to which the boundary will be appended. Additional Args --------------- ** kwargs forwarded to :py:mod:`pygimli.meshtools.appendTriangleBoundary` or :py:mod:`pygimli.meshtools.appendTetrahedronBoundary`. Returns ------- :gimliapi:`GIMLI::Mesh` A new 2D or 3D mesh containing the original mesh and a boundary around. """ if mesh.dim() == 2: return appendTriangleBoundary(mesh, **kwargs) elif mesh.dim() == 3: return appendTetrahedronBoundary(mesh, **kwargs) pg.critical("Don't know how to append boundary to: ", mesh)
def setForwardOperator(self, fop): if not isinstance(fop, pg.frameworks.PetroModelling): pg.critical( 'Forward operator needs to be an instance of ' 'pg.modelling.PetroModelling but is of type:', fop) return super(PetroInversion, self).setForwardOperator(fop)
def toSparseMapMatrix(A): """Convert any matrix type to pg.SparseMatrix and return copy of it. Arguments --------- A: pg or scipy matrix Returns ------- pg.SparseMatrix """ if isinstance(A, pg.matrix.SparseMapMatrix): return pg.matrix.SparseMapMatrix(A) if isinstance(A, pg.matrix.BlockMatrix): return A.sparseMapMatrix() if isinstance(A, pg.matrix.SparseMatrix): return pg.matrix.SparseMapMatrix(A) from scipy.sparse import csr_matrix if isinstance(A, csr_matrix): pg.critical('implement me') return pg.matrix.SparseMapMatrix(A) from scipy.sparse import coo_matrix if isinstance(A, coo_matrix): pg.critical('implement me') return pg.matrix.SparseMapMatrix(A) return toSparseMapMatrix(csr_matrix(A))
def fop(self, fop): """""" if fop is not None: if not isinstance(fop, pg.frameworks.Modelling): pg.critical('Forward operator needs to be an instance of ' 'pg.modelling.Modelling but is of type:', fop) self._fop = fop
def checkData(self, data): """Return data from container""" if isinstance(data, pg.DataContainer): if not data.haveData('t'): pg.critical('DataContainer has no "t" values.') return data['t'] return data
def response(self, params): if np.isnan([*params]).any(): print(params) pg.critical('invalid params for response') if self.dataSpace is None: pg.critical('no data space given') ret = self.function(self.dataSpace, *params) return ret
def drawModel(self, ax, model, **kwargs): """ """ if self.fop is not None: pg.critical('in use?') self.fop.drawModel(ax, model, **kwargs) else: print(kwargs) raise Exception("No yet implemented")
def paraDomain(self): """""" # We need our own copy here because its possible that we want to use # the mesh after the fop was deleted if not self.mesh(): pg.critical('paraDomain needs a mesh') self._pd = pg.Mesh(self.regionManager().paraDomain()) return self._pd
def dataVals(self, d): """Set mandatory data values. Values == 0.0. Will be set to Tolerance """ self._dataVals = d if self._dataVals is None: pg._y(d) pg.critical("Inversion framework needs data values to run")
def response_mt(self, par, i=0): if self.am is not None and self.bm is not None: nLayers = (len(par) + 1) // 2 fop = pg.core.DC1dModelling(nLayers, self.am, self.bm, self.an, self.bn) else: pg.critical("No data space defined don't know what to calculate.") return fop.response(par)
def checkError(self, err, data=None): """Collect error values.""" if len(err) != len(self.mgrs): pg.critical("Please provide data for all managers") vals = pg.Vector(0) for i, mgr in enumerate(self.mgrs): # we get the data values again or we have to split data dataVals = mgr.checkData(self.fop._data[i]) vals = pg.cat(vals, mgr.checkError(err[i], dataVals)) return vals
def __init__(self, petro, fop=None, **kwargs): """ Parameters ---------- """ pg.critical('Obsolete .. to be removed.') if fop is not None: if not isinstance(fop, pg.frameworks.PetroModelling): fop = pg.frameworks.PetroModelling(fop, petro) super(PetroInversion, self).__init__(fop=fop, **kwargs)
def createMesh(self, data=None, **kwargs): """Create default inversion mesh. Inversion mesh for traveltime inversion does not need boundary region. """ d = data or self.data if d is None: pg.critical('Please provide a data file for mesh generation') return pg.meshtools.createParaMesh(d.sensors(), boundary=0, **kwargs)
def _initInversionFramework(self, **kwargs): """Initialize or re-initialize the inversion framework. Called once in the constructor to force the manager to create the necessary Framework instance. """ self._fw = self.createInversionFramework(**kwargs) if self.fw is None: pg.critical("createInversionFramework does not return " "valid inversion framework.")
def createMesh(self, data=None, **kwargs): """Create default inversion mesh Forwarded to :py:mod:`pygimli.physics.ert.createInversionMesh` """ d = data or self.data if d is None: pg.critical('Please provide a data file for mesh generation') return createInversionMesh(d, **kwargs)
def setDataContainer(self, data): """ """ if self.fop is not None: pg.critical('in use?') self.fop.setData(data) else: super(Modelling, self).setData(data) self._data = data self.setDataPost(self.data)
def setMappableValues(mappable, dataIn): """Change the data values for a given mapable.""" pg.critical('remove me') data = dataIn if not isinstance(data, np.ma.core.MaskedArray): data = np.array(dataIn) # set bad value color to white if mappable.get_cmap() is not None: mappable.get_cmap().set_bad([1.0, 1.0, 1.0, 0.0]) mappable.set_array(data)
def setDataSpace(self, **kwargs): """Set data space, e.g., DataContainer, times, coordinates.""" if self.fop is not None: pg.critical('in use?') self.fop.setDataSpace(**kwargs) else: data = kwargs.pop('dataContainer', None) if isinstance(data, pg.DataContainer): self.setDataContainer(data) else: print(data) pg.critical("nothing known to do? Implement me in derived classes")
def setData(self, data): """Distribute list of data to the forward operators """ if len(data) != len(self.fops): pg.critical("Please provide data for all forward operators") self._data = data nData = 0 for i, fi in enumerate(self.fops): fi.setData(data[i]) self.jac.addMatrix(fi.jacobian(), nData, 0) nData += data[i].size() # update total vector length self.setJacobian(self.jac)
def __init__(self, funct=None, fop=None, **kwargs): """Constructor.""" if fop is not None: if not isinstance(fop, pg.frameworks.ParameterModelling): pg.critical("We need a fop if type ", pg.frameworks.ParameterModelling) elif funct is not None: fop = pg.frameworks.ParameterModelling(funct) else: pg.critical("you should either give a valid fop or a function so " "I can create the fop for you") super(ParameterInversionManager, self).__init__(fop, **kwargs)
def response_mt(self, par, i=0): """ Multithread response for parametrization. Returns [|rhoa|, +phi(rad)] for [thicks, res, phi(rad)] """ if self.am is not None and self.bm is not None: nLayers = (len(par) + 1) // 3 fop = pg.core.DC1dModellingC(nLayers, self.am, self.bm, self.an, self.bn) else: pg.critical("No data basis known.") return fop.response(par)
def checkData(self, data): """Collect data values.""" if len(data) != len(self.mgrs): pg.critical("Please provide data for all managers") self.dataTrans.clear() vals = pg.Vector(0) for i, mgr in enumerate(self.mgrs): self.dataTrans.add(mgr.inv.dataTrans, data[i].size()) vals = pg.cat(vals, mgr.checkData(data[i])) self.inv.dataTrans = self.dataTrans return vals
def run(self, dataVals, errorVals, **kwargs): """ """ if 'limits' in kwargs: limits = kwargs.pop('limits') if len(self.fop.regionManager().regionIdxs()) > 1: pg.critical('implement') else: self.fop.setRegionProperties('*', limits=limits) #ensure the mesh self.fop.mesh() return super(PetroInversion, self).run(dataVals, errorVals, **kwargs)
def errorVals(self, d): """Set mandatory error values. Values == 0.0. Will be set to Tolerance """ self._errorVals = d if self._errorVals is None: pg._y(d) pg.critical("Inversion framework needs error values to run") if min(abs(self._errorVals)) < 1e-12: print(self._errorVals) pg.warn("Found zero error values. Setting them to a Fallback value of 1") pg.fixZero(self._errorVals, 1)
def _ensureData(self, data): """Check data validity""" if data is None: data = self.fw.dataVals vals = self.checkData(data) if vals is None: pg.critical("There are no data values.") if abs(min(vals)) < 1e-12: print(min(vals), max(vals)) pg.critical("There are zero data values.") return vals
def load(fileName, verbose=False, **kwargs): """Shortcut to load ERT data. Import Data and try to assume the file format. Additionally to unified data format we support the wide-spread res2dinv format as well as ASCII column files generated by the processing software of various instruments (ABEM LS, Syscal Pro, Resecs, ?) If this fails, install pybert and use its auto importer pybert.importData. Parameters ---------- fileName: str Returns ------- data: pg.DataContainer """ data = pg.load(fileName) if isinstance(data, pg.DataContainerERT): return data try: pg.info("could not read unified data format for ERT ... try res2dinv") data = importRes2dInv(fileName) return data except: pg.info("could not read res2dinv ... try Ascii columns") try: data = importAsciiColumns(fileName) return data except Exception as e: pg.info("Failed importing Ascii column file. Consider using pybert.") pg.info(e) if verbose: pg.info("Try to import using pybert .. if available") pb = pg.optImport('pybert') data = pb.loadData(fileName) if isinstance(data, pg.DataContainerERT): return data pg.critical("Can't import ERT data file.", fileName)
def _ensureError(self, err, dataVals=None): """Check data validity""" if isinstance(err, pg.DataContainer): pg.critical("Implement me") if err is None: err = self.fw.errorVals vals = err if vals is None: return self._ensureError(0.01, dataVals) if abs(min(vals)) < 1e-12: print(min(vals), max(vals)) pg.critical("There are zero data values.") return vals
def createStartModel(self, rhoa): r""" """ if self.nLayers == 0: pg.critical("Model space is not been initialized.") startThicks = np.logspace(np.log10(min(self.mn2) / 2), np.log10(max(self.ab2) / 5), self.nLayers - 1) startThicks = pg.utils.diff(pg.cat([0.0], startThicks)) # layer thickness properties self.setRegionProperties(0, startModel=startThicks, trans='log') # resistivity properties self.setRegionProperties(1, startModel=np.median(rhoa), trans='log') return super(VESModelling, self).createStartModel()