Source code for pygimli.frameworks.timelapse

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import numpy as np
import pygimli as pg
from .modelling import MeshModelling


[docs] class MultiFrameModelling(MeshModelling): """Full frame (multiple fop parallel) forward modelling."""
[docs] def __init__(self, modellingOperator, scalef=1.0, **ini): """Init class and jacobian matrix.""" super().__init__() self.ini = ini self.modellingOperator = modellingOperator self.jac = pg.matrix.BlockMatrix() self.scalef = scalef self.fops = [] self.nf = 0 self.nm = 0
[docs] def setData(self, data, modellingOperator=None, **ini): """Distribute the data containers amongst the fops.""" modellingOperator = modellingOperator or self.modellingOperator ini = self.ini or ini self.fops = [] for datai in data: fopi = modellingOperator(**ini) fopi.setData(datai) # fopi.setData(pg.Vector(datai)) self.fops.append(fopi)
[docs] def setMeshPost(self, mesh): """Set mesh to all forward operators.""" for fop in self.fops: fop.setMesh(mesh, ignoreRegionManager=True) self.prepareJacobian()
[docs] def setDefaultBackground(self): """Set the default background behaviour.""" regionIds = self.regionManager().regionIdxs() pg.info("Found {} regions.".format(len(regionIds))) if len(regionIds) > 1: bk = pg.sort(regionIds)[0] pg.info("Region with smallest marker ({0}) " "set to background".format(bk)) self.setRegionProperties(bk, background=True)
@property def parameterCount(self): """Return number of parameters.""" pc = self.regionManager().parameterCount() if pc == 0: pc = self.fops[0].parameterCount return pc * len(self.fops)
[docs] def prepareJacobian(self): """Build up Jacobian block matrix (once the sizes are known).""" self.jac.clear() self.nm = self.regionManager().parameterCount() if self.nm == 0: self.nm = self.fops[0].parameterCount self.nf = len(self.fops) print(self.nm, "model cells") nd = 0 for i, fop in enumerate(self.fops): self.jac.addMatrix(fop.jacobian(), nd, i*self.nm) nd += fop.data.size() self.jac.recalcMatrixSize() self.setJacobian(self.jac)
[docs] def createConstraints(self, C=None): """Create constraint matrix (special type for this).""" if C is not None: self.C1 = C elif isinstance(super().createConstraints(), pg.SparseMapMatrix): self.C1 = pg.SparseMapMatrix(self.constraintsRef()) # make a copy because it will be overwritten else: self.C1 = self.constraints() self.C = pg.matrix.FrameConstraintMatrix(self.C1, len(self.fops), self.scalef) self.setConstraints(self.C) # cw = self.regionManager().constraintWeights() # self.regionManager().setConstraintsWeights(np.tile(cw, self.nf)) # switch off automagic inside core.inversion which checks for # local modeltransform of the regionManager self.regionManager().setLocalTransFlag(False)
[docs] def response(self, model): """Forward response.""" mod = np.reshape(model, [len(self.fops), -1]) return np.concatenate([fop.response(mo) for fop, mo in zip(self.fops, mod)])
[docs] def createJacobian(self, model): """Create Jacobian matrix.""" mod = np.reshape(model, [len(self.fops), -1]) for i, fop in enumerate(self.fops): fop.createJacobian(mod[i])
[docs] def createDefaultStartModel(self): # , dataVals): """Create standard starting model.""" return pg.Vector(self.nm*self.nf, 10.0) # look up in fop
[docs] def createStartModel(self, dataVals): """Create a starting model from mean data values.""" # return np.concatenate([f.createStartModel() for f in self.fops]) self.nm = self.regionManager().parameterCount() return pg.Vector(self.nm*len(self.fops), np.median(dataVals))