def perform(self, node, inputs, output): """ Perform method of the Operator to calculate synthetic displacements. Parameters ---------- inputs : list of :class:`numpy.ndarray` output : list of synthetic displacements of :class:`numpy.ndarray` (n x 3) """ z = output[0] point = {vname: i for vname, i in zip(self.varnames, inputs)} point.update(self.fixed_values) point = utility.adjust_point_units(point) spoint, bpoint = interseismic.seperate_point(point) source_points = utility.split_point(spoint) for i, source_point in enumerate(source_points): self.sources[i].update(**source_point) z[0] = interseismic.geo_backslip_synthetics( engine=self.engine, targets=self.targets, sources=self.sources, lons=num.array(self.lons), lats=num.array(self.lats), reference=self.reference, **bpoint) def infer_shape(self, node, input_shapes): return [(len(self.lats), 3)]
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 point2sources(self, point): """ Updates the composite source(s) (in place) with the point values. """ tpoint = copy.deepcopy(point) tpoint = utility.adjust_point_units(tpoint) # remove hyperparameters from point hps = self.config.get_hypernames() for hyper in hps: if hyper in tpoint: tpoint.pop(hyper) source_params = self.sources[0].keys() for param in tpoint.keys(): if param not in source_params: tpoint.pop(param) source_points = utility.split_point(tpoint) 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.
def perform(self, node, inputs, output): """ Perform method of the Operator to calculate synthetic displacements. Parameters ---------- inputs : list of :class:`numpy.ndarray` output : list of synthetic displacements of :class:`numpy.ndarray` (n x 1) """ z = output[0] point = {vname: i for vname, i in zip(self.varnames, inputs)} point = utility.adjust_point_units(point) source_points = utility.split_point(point) for i, source in enumerate(self.sources): source.update(**source_points[i]) z[0] = heart.geo_layer_synthetics_pscmp( store_superdir=self.store_superdir, crust_ind=self.crust_ind, lons=self.lons, lats=self.lats, sources=self.sources)
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] tmins = output[1] 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]) source.time += self.event.time synths[0], tmins[0] = heart.seis_synthetics( engine=self.engine, sources=self.sources, targets=self.targets, arrival_taper=self.arrival_taper, wavename=self.wavename, filterer=self.filterer, pre_stack_cut=self.pre_stack_cut)
def point2sources(self, point): """ Updates the composite source(s) (in place) with the point values. """ tpoint = copy.deepcopy(point) tpoint = utility.adjust_point_units(tpoint) # remove hyperparameters from point hps = self.config.get_hypernames() for hyper in hps: if hyper in tpoint: tpoint.pop(hyper) source = self.sources[0] source_params = source.keys() + source.stf.keys() for param in tpoint.keys(): if param not in source_params: tpoint.pop(param) tpoint['time'] += self.event.time source_points = utility.split_point(tpoint) for i, source in enumerate(self.sources): utility.update_source(source, **source_points[i])
def perform(self, node, inputs, output): z = output[0] lons = inputs.pop(0) lats = inputs.pop(0) point = {var: inp for var, inp in zip(config.geo_vars_magma, inputs)} point = utility.adjust_point_units(point) source_points = utility.split_point(point) for i, source in enumerate(self.sources): source.update(**source_points[i]) heart.adjust_fault_reference(source, input_depth='top') z[0] = heart.geo_layer_synthetics(self.store_superdir, self.crust_ind, lons, lats, self.sources)
def perform(self, node, inputs, output): synths = output[0] tmins = output[1] point = { var: inp for var, inp in zip(config.joint_vars_geometry, 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]) source.time += self.event.time heart.adjust_fault_reference(source, input_depth='top') synths[0], tmins[0] = heart.seis_synthetics(self.engine, self.sources, self.targets, self.arrival_taper, self.filterer)
def point2sources(self, point): """ Updates the composite source(s) (in place) with the point values. Parameters ---------- point : dict with random variables from solution space """ tpoint = copy.deepcopy(point) tpoint = utility.adjust_point_units(tpoint) # remove hyperparameters from point hps = self.config.get_hypernames() for hyper in hps: if hyper in tpoint: tpoint.pop(hyper) source = self.sources[0] source_params = list(source.keys()) + list(source.stf.keys()) for param in list(tpoint.keys()): if param not in source_params: tpoint.pop(param) # update source times if self.nevents == 1: tpoint['time'] += self.event.time # single event else: for i, event in enumerate(self.events): # multi event tpoint['time'][i] += event.time source_points = utility.split_point(tpoint) for i, source in enumerate(self.sources): utility.update_source(source, **source_points[i])
def point2sources(self, point, input_depth='top'): """ Updates the composite source(s) (in place) with the point values. Parameters ---------- point : dict with random variables from solution space input_depth : string may be either 'top'- input coordinates are transformed to center 'center' - input coordinates are not transformed """ tpoint = copy.deepcopy(point) tpoint = utility.adjust_point_units(tpoint) # remove hyperparameters from point hps = self.config.get_hypernames() for hyper in hps: if hyper in tpoint: tpoint.pop(hyper) source = self.sources[0] source_params = list(source.keys()) + list(source.stf.keys()) for param in list(tpoint.keys()): if param not in source_params: tpoint.pop(param) tpoint['time'] += self.event.time source_points = utility.split_point(tpoint) for i, source in enumerate(self.sources): utility.update_source(source, input_depth=input_depth, **source_points[i])
def init_config(name, date=None, min_magnitude=6.0, main_path='./', datatypes=['geodetic'], mode='geometry', source_type='RectangularSource', n_sources=1, waveforms=['any_P'], sampler='SMC', hyper_sampler='Metropolis', use_custom=False, individual_gfs=False): """ Initialise BEATconfig File and write it main_path/name . Fine parameters have to be edited in the config file .yaml manually. Parameters ---------- name : str Name of the event date : str 'YYYY-MM-DD', date of the event min_magnitude : scalar, float approximate minimum Mw of the event datatypes : List of strings data sets to include in the optimization: either 'geodetic' and/or 'seismic' mode : str type of optimization problem: 'Geometry' / 'Static'/ 'Kinematic' n_sources : int number of sources to solve for / discretize depending on mode parameter waveforms : list of strings of waveforms to include into the misfit function and GF calculation sampler : str Optimization algorithm to use to sample the solution space Options: 'SMC', 'Metropolis' use_custom : boolean Flag to setup manually a custom velocity model. individual_gfs : boolean Flag to use individual Green's Functions for each specific station. If false a reference location will be initialised in the config file. If true the reference locations will be taken from the imported station objects. Returns ------- :class:`BEATconfig` """ c = BEATconfig(name=name, date=date) c.project_dir = os.path.join(os.path.abspath(main_path), name) if mode == 'geometry' or mode == 'interseismic': if date is not None and not mode == 'interseismic': c.event = utility.search_catalog(date=date, min_magnitude=min_magnitude) elif mode == 'interseismic': c.event = model.Event(lat=10., lon=10., depth=0.) c.date = 'dummy' logger.info('Interseismic mode! Using event as reference for the' ' stable block! Please update coordinates!') else: logger.warn('No given date! Using dummy event!' ' Updating reference coordinates (spatial & temporal)' ' necessary!') c.event = model.Event(duration=1.) c.date = 'dummy' if 'geodetic' in datatypes: c.geodetic_config = GeodeticConfig() if use_custom: logger.info('use_custom flag set! The velocity model in the' ' geodetic GF configuration has to be updated!') c.geodetic_config.gf_config.custom_velocity_model = \ load_model().extract(depth_max=100. * km) c.geodetic_config.gf_config.use_crust2 = False c.geodetic_config.gf_config.replace_water = False else: c.geodetic_config = None if 'seismic' in datatypes: c.seismic_config = SeismicConfig() c.seismic_config.init_waveforms(waveforms) if not individual_gfs: c.seismic_config.gf_config.reference_location = \ ReferenceLocation(lat=10.0, lon=10.0) else: c.seismic_config.gf_config.reference_location = None if use_custom: logger.info('use_custom flag set! The velocity model in the' ' seismic GF configuration has to be updated!') c.seismic_config.gf_config.custom_velocity_model = \ load_model().extract(depth_max=100. * km) c.seismic_config.gf_config.use_crust2 = False c.seismic_config.gf_config.replace_water = False else: c.seismic_config = None elif mode == 'ffi': if source_type != 'RectangularSource': raise TypeError('Static distributed slip is so far only supported' ' for RectangularSource(s)') gmc = load_config(c.project_dir, 'geometry') if gmc is not None: logger.info('Taking information from geometry_config ...') if source_type != gmc.problem_config.source_type: raise ValueError( 'Specified reference source: "%s" differs from the' ' source that has been used previously in' ' "geometry" mode: "%s"!' % (source_type, gmc.problem_config.source_type)) n_sources = gmc.problem_config.n_sources point = { k: v.testvalue for k, v in gmc.problem_config.priors.iteritems() } point = utility.adjust_point_units(point) source_points = utility.split_point(point) reference_sources = init_reference_sources( source_points, n_sources, gmc.problem_config.source_type, gmc.problem_config.stf_type) c.date = gmc.date c.event = gmc.event if 'geodetic' in datatypes: gc = gmc.geodetic_config if gc is None: logger.warning( 'Asked for "geodetic" datatype but geometry config ' 'has no such datatype! Initialising default "geodetic"' ' linear config!') gc = GeodeticConfig() lgf_config = GeodeticLinearGFConfig() else: lgf_config = GeodeticLinearGFConfig( earth_model_name=gc.gf_config.earth_model_name, store_superdir=gc.gf_config.store_superdir, n_variations=gc.gf_config.n_variations, reference_sources=reference_sources, sample_rate=gc.gf_config.sample_rate) c.geodetic_config = gc c.geodetic_config.gf_config = lgf_config elif 'seismic' in datatypes: sc = gmc.seismic_config if sc is None: logger.warning( 'Asked for "seismic" datatype but geometry config ' 'has no such datatype! Initialising default "seismic"' ' linear config!') sc = SeismicConfig() lgf_config = SeismicLinearGFConfig() else: lgf_config = SeismicLinearGFConfig( earth_model_name=sc.gf_config.earth_model_name, sample_rate=sc.gf_config.sample_rate, reference_location=sc.gf_config.reference_location, store_superdir=sc.gf_config.store_superdir, n_variations=sc.gf_config.n_variations, reference_sources=reference_sources) c.seismic_config = sc c.seismic_config.gf_config = lgf_config else: logger.warning('Found no geometry setup, ...') raise ImportError( 'No geometry configuration file existing! Please initialise' ' a "geometry" configuration ("beat init command"), update' ' the Greens Function information and create GreensFunction' ' stores for the non-linear problem.') c.problem_config = ProblemConfig(n_sources=n_sources, datatypes=datatypes, mode=mode, source_type=source_type) c.problem_config.init_vars() c.problem_config.set_decimation_factor() c.sampler_config = SamplerConfig(name=sampler) c.sampler_config.set_parameters(update_covariances=False) c.hyper_sampler_config = SamplerConfig(name=hyper_sampler) c.hyper_sampler_config.set_parameters(update_covariances=None) c.update_hypers() c.problem_config.validate_priors() c.regularize() c.validate() logger.info('Project_directory: %s \n' % c.project_dir) util.ensuredir(c.project_dir) dump_config(c) return c
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 seismic forward model outmode = 'traces'/ 'array' / 'data' Returns ------- Dictionary with keys according to datasets containing the synthetics as lists. """ tpoint = copy.deepcopy(point) tpoint = utility.adjust_point_units(tpoint) # remove hyperparameters from point hps = self.config.problem_config.hyperparameters if len(hps) > 0: for hyper in hps.keys(): if hyper in tpoint: tpoint.pop(hyper) else: pass d = dict() if self._seismic_flag: tpoint['time'] += self.event.time source_points = utility.split_point(tpoint) for i, source in enumerate(self.sources): utility.update_source(source, **source_points[i]) dsources = utility.transform_sources( self.sources, self.config.problem_config.datasets) # seismic if self._seismic_flag: sc = self.config.seismic_config seis_synths, _ = heart.seis_synthetics( engine=self.engine, sources=dsources['seismic'], targets=self.stargets, arrival_taper=sc.arrival_taper, filterer=sc.filterer, **kwargs) d['seismic'] = seis_synths # geodetic if self._geodetic_flag: gc = self.config.geodetic_config crust_inds = [0] geo_synths = [] for crust_ind in crust_inds: for gtarget in self.gtargets: disp = heart.geo_layer_synthetics( gc.gf_config.store_superdir, crust_ind, lons=gtarget.lons, lats=gtarget.lats, sources=dsources['geodetic']) geo_synths.append(( disp[:, 0] * gtarget.los_vector[:, 0] + \ disp[:, 1] * gtarget.los_vector[:, 1] + \ disp[:, 2] * gtarget.los_vector[:, 2])) d['geodetic'] = geo_synths return d
def update_weights(self, point, n_jobs=1, plot=False): """ Calculate and update model prediction uncertainty covariances due to uncertainty in the velocity model with respect to one point in the solution space. Shared variables are updated. Parameters ---------- point : :func:`pymc3.Point` Dictionary with model parameters, for which the covariance matrixes with respect to velocity model uncertainties are calculated n_jobs : int Number of processors to use for calculation of seismic covariances plot : boolean Flag for opening the seismic waveforms in the snuffler """ tpoint = copy.deepcopy(point) # update sources tpoint = utility.adjust_point_units(tpoint) # remove hyperparameters from point hps = self.config.problem_config.hyperparameters if len(hps) > 0: for hyper in hps.keys(): tpoint.pop(hyper) if self._seismic_flag: tpoint['time'] += self.event.time source_points = utility.split_point(tpoint) for i, source in enumerate(self.sources): utility.update_source(source, **source_points[i]) dsources = utility.transform_sources( self.sources, self.config.problem_config.datasets) # seismic if self._seismic_flag: sc = self.config.seismic_config for j, channel in enumerate(sc.channels): for i, station in enumerate(self.stations): logger.debug('Channel %s of Station %s ' % ( channel, station.station)) crust_targets = heart.init_targets( stations=[station], channels=channel, sample_rate=sc.gf_config.sample_rate, crust_inds=range(sc.gf_config.n_variations)) cov_pv = cov.get_seis_cov_velocity_models( engine=self.engine, sources=dsources['seismic'], targets=crust_targets, arrival_taper=sc.arrival_taper, filterer=sc.filterer, plot=plot, n_jobs=n_jobs) cov_pv = utility.ensure_cov_psd(cov_pv) self.engine.close_cashed_stores() index = j * len(self.stations) + i self.stargets[index].covariance.pred_v = cov_pv icov = self.stargets[index].covariance.inverse self.sweights[index].set_value(icov) # geodetic if self._geodetic_flag: gc = self.config.geodetic_config for i, gtarget in enumerate(self.gtargets): logger.debug('Track %s' % gtarget.track) cov_pv = cov.get_geo_cov_velocity_models( store_superdir=gc.gf_config.store_superdir, crust_inds=range(gc.gf_config.n_variations), dataset=gtarget, sources=dsources['geodetic']) cov_pv = utility.ensure_cov_psd(cov_pv) gtarget.covariance.pred_v = cov_pv icov = gtarget.covariance.inverse self.gweights[i].set_value(icov)