def perform(self, node, inputs, output): """ Perform method of the Operator to calculate synthetic displacements. Parameters ---------- inputs : list of :class:`numpy.ndarray` output : list 1) of synthetic waveforms of :class:`numpy.ndarray` (n x nsamples) 2) of start times of the first waveform samples :class:`numpy.ndarray` (n x 1) """ synths = output[0] point = {vname: i for vname, i in zip(self.varnames, inputs)} mpoint = utility.adjust_point_units(point) source_points = utility.split_point(mpoint) for i, source in enumerate(self.sources): utility.update_source(source, **source_points[i]) # reset source time may result in store error otherwise source.time = 0. synths[0] = heart.geo_synthetics( engine=self.engine, targets=self.targets, sources=self.sources, outmode='stacked_array')
def get_synthetics(self, point, **kwargs): """ Get synthetics for given point in solution space. Parameters ---------- point : :func:`pymc3.Point` Dictionary with model parameters kwargs especially to change output of the forward model Returns ------- list with :class:`numpy.ndarray` synthetics for each target """ self.point2sources(point) displacements = heart.geo_synthetics(engine=self.engine, targets=self.targets, sources=self.sources, **kwargs) synths = [] for disp, data in zip(displacements, self.datasets): los_d = (disp * data.los_vector).sum(axis=1) synths.append(los_d) if self.config.fit_plane: synths = self.remove_ramps(synths, point=point, operation='+') return synths
def geo_backslip_synthetics(engine, sources, targets, lons, lats, reference, amplitude, azimuth, locking_depth): """ Interseismic backslip model: forward model for synthetic displacements(n,e,d) [m] caused by a rigid moving block defined by the bounding geometry of rectangular faults. The reference location determines the stable regions. The amplitude and azimuth determines the amount and direction of the moving block. Based on this block-movement the upper part of the crust that is not locked is assumed to slip back. Thus the final synthetics are the superposition of the block-movement and the backslip. Parameters ---------- engine : :class:`pyrocko.gf.seismosizer.LocalEngine` sources : list of :class:`pyrocko.gf.seismosizer.RectangularSource` Sources to calculate synthetics for targets : list of :class:`pyrocko.gf.targets.StaticTarget` lons : list of floats, or :class:`numpy.ndarray` longitudes [deg] of observation points lats : list of floats, or :class:`numpy.ndarray` latitudes [deg] of observation points amplitude : float slip [m] of the moving block azimuth : float azimuth-angle[deg] ergo direction of moving block towards North locking_depth : :class:`numpy.ndarray` locking_depth [km] of the fault(s) below there is no movement reference : :class:`heart.ReferenceLocation` reference location that determines the stable block Returns ------- :class:`numpy.ndarray` (n x 3) [North, East, Down] displacements [m] """ disp_block = geo_block_synthetics(lons, lats, sources, amplitude, azimuth, reference) for source, ld in zip(sources, locking_depth): source_params = backslip_params(azimuth=azimuth, amplitude=amplitude, locking_depth=ld, strike=source.strike, dip=source.dip) source.update(**source_params) disp_block += geo_synthetics(engine=engine, targets=targets, sources=sources, outmode='stacked_array') return disp_block
def _process_patch_geodetic(engine, gfs, targets, patch, patchidx, los_vectors, odws): logger.info('Patch Number %i', patchidx) logger.debug('Calculating synthetics ...') disp = heart.geo_synthetics(engine=engine, targets=targets, sources=[patch], outmode='stacked_array') logger.debug('Applying LOS vector ...') los_disp = (disp * los_vectors).sum(axis=1) * odws gfs.put(entries=los_disp, patchidx=patchidx)
def geodetic_cov_velocity_models(engine, sources, targets, dataset, plot=False, event=None, n_jobs=1): """ Calculate model prediction uncertainty matrix with respect to uncertainties in the velocity model for geodetic targets using fomosto GF stores. Parameters ---------- engine : :class:`pyrocko.gf.seismosizer.LocalEngine` contains synthetics generation machine target : :class:`pyrocko.gf.targets.StaticTarget` dataset and observation points to calculate covariance for sources : list of :py:class:`pyrocko.gf.seismosizer.Source` determines the covariance matrix plot : boolean if set, a plot is produced and not covariance matrix is returned Returns ------- :class:`numpy.ndarray` with Covariance due to velocity model uncertainties """ t0 = time() displacements = heart.geo_synthetics(engine=engine, targets=targets, sources=sources, outmode='stacked_arrays') t1 = time() logger.debug('Synthetics generation time %f' % (t1 - t0)) synths = num.zeros((len(targets), dataset.samples)) for i, disp in enumerate(displacements): synths[i, :] = (disp[:, 0] * dataset.los_vector[:, 0] + disp[:, 1] * dataset.los_vector[:, 1] + disp[:, 2] * dataset.los_vector[:, 2]) * dataset.odw if plot: from matplotlib import pyplot as plt indexes = dataset.get_distances_to_event(event).argsort() ax = plt.axes() im = ax.matshow(synths) # [:, indexes]) plt.colorbar(im) plt.show() return num.cov(synths, rowvar=0)
def _process_patch_geodetic( engine, gfs, targets, patch, patchidx, los_vectors, odws): logger.debug('Patch Number %i', patchidx) logger.debug('Calculating synthetics ...') disp = heart.geo_synthetics( engine=engine, targets=targets, sources=[patch], outmode='stacked_array') logger.debug('Applying LOS vector ...') los_disp = (disp * los_vectors).sum(axis=1) * odws if isinstance(gfs, GeodeticGFLibrary): gfs.put(entries=los_disp, patchidx=patchidx) elif gfs is None and hasattr(parallel, 'gfmatrix'): npatches = len(parallel.gfmatrix) // los_disp.size matrix = num.frombuffer(parallel.gfmatrix).reshape( (npatches, los_disp.size)) matrix[patchidx, :] = los_disp else: raise ValueError('GF Library not allocated!')