def get_data_covariances( self, wmap, sample_rate, results=None, chop_bounds=None): """ Estimated data covariances of seismic traces Parameters ---------- wmap : :class:`eat.WaveformMapping` results sample_rate : float sampling rate of data_traces and GreensFunction stores Returns ------- :class:`numpy.ndarray` """ covariance_structure = self.get_structure( wmap, sample_rate, chop_bounds) if self.structure == 'import': scalings = self.do_import(wmap, sample_rate) elif self.structure == 'non-toeplitz': scalings = self.do_non_toeplitz(wmap, results) else: scalings = self.do_variance_estimate(wmap) cov_ds = [] for scaling in scalings: cov_d = ensure_cov_psd(scaling * covariance_structure) cov_ds.append(cov_d) return cov_ds
def update_weights(self, point, n_jobs=1, plot=False): """ Updates weighting matrixes (in place) with respect to the point in the solution space. Parameters ---------- point : dict with numpy array-like items and variable name keys """ sc = self.config self.point2sources(point) for wmap in self.wavemaps: wc = wmap.config for channel in wmap.channels: datasets = wmap.get_datasets([channel]) weights = wmap.get_weights([channel]) for station, dataset, weight in zip(wmap.stations, datasets, weights): logger.debug('Channel %s of Station %s ' % (channel, station.station)) crust_targets = heart.init_seismic_targets( stations=[station], earth_model_name=sc.gf_config.earth_model_name, channels=channel, sample_rate=sc.gf_config.sample_rate, crust_inds=range(*sc.gf_config.n_variations), reference_location=sc.gf_config.reference_location) cov_pv = cov.seismic_cov_velocity_models( engine=self.engine, sources=self.sources, targets=crust_targets, wavename=wmap.name, arrival_taper=wc.arrival_taper, filterer=wc.filterer, plot=plot, n_jobs=n_jobs) cov_pv = utility.ensure_cov_psd(cov_pv) self.engine.close_cashed_stores() dataset.covariance.pred_v = cov_pv t0 = time() choli = dataset.covariance.chol_inverse t1 = time() logger.debug('Calculate weight time %f' % (t1 - t0)) weight.set_value(choli) dataset.covariance.update_slog_pdet()
def update_weights(self, point, n_jobs=1, plot=False): """ Updates weighting matrixes (in place) with respect to the point in the solution space. Parameters ---------- point : dict with numpy array-like items and variable name keys """ gc = self.config crust_inds = range(*gc.gf_config.n_variations) thresh = 5 if len(crust_inds) > thresh: logger.info('Updating geodetic velocity model-covariances ...') crust_inds = list(range(*self.config.gf_config.n_variations)) n_variations = len(crust_inds) if len(self.gfs) != n_variations: logger.info('Loading geodetic linear GF matrixes ...') self.load_gfs(crust_inds=crust_inds, make_shared=False) crust_displacements = num.zeros( (n_variations, self.Bij.ordering.size)) for i, crust_ind in enumerate(crust_inds): mu = num.zeros((self.Bij.ordering.size)) for var in self.slip_varnames: key = self.get_gflibrary_key(crust_ind=crust_ind, wavename='static', component=var) mu += self.gfs[key].stack_all(slips=point[var]) crust_displacements[i, :] = mu crust_synths = self.Bij.a_nd2l(crust_displacements) if len(crust_synths) != self.n_t: raise ValueError( 'Number of datasets %i and number of synthetics %i ' 'inconsistent!' % (self.n_t, len(crust_synths))) for i, data in enumerate(self.datasets): logger.debug('Track %s' % data.name) cov_pv = num.cov(crust_synths[i], rowvar=0) cov_pv = utility.ensure_cov_psd(cov_pv) data.covariance.pred_v = cov_pv choli = data.covariance.chol_inverse self.weights[i].set_value(choli) data.covariance.update_slog_pdet() else: logger.info( 'Not updating geodetic velocity model-covariances because ' 'number of model variations is too low! < %i' % thresh)
def update_weights(self, point, n_jobs=1, plot=False): """ Updates weighting matrixes (in place) with respect to the point in the solution space. Parameters ---------- point : dict with numpy array-like items and variable name keys """ gc = self.config self.point2sources(point) crust_inds = range(*gc.gf_config.n_variations) thresh = 5 if len(crust_inds) > thresh: logger.info('Updating geodetic velocity model-covariances ...') for i, data in enumerate(self.datasets): crust_targets = heart.init_geodetic_targets( datasets=[data], earth_model_name=gc.gf_config.earth_model_name, interpolation=gc.interpolation, crust_inds=crust_inds, sample_rate=gc.gf_config.sample_rate) logger.debug('Track %s' % data.name) cov_pv = cov.geodetic_cov_velocity_models( engine=self.engine, sources=self.sources, targets=crust_targets, dataset=data, plot=plot, event=self.event, n_jobs=1) cov_pv = utility.ensure_cov_psd(cov_pv) data.covariance.pred_v = cov_pv choli = data.covariance.chol_inverse self.weights[i].set_value(choli) data.covariance.update_slog_pdet() else: logger.info( 'Not updating geodetic velocity model-covariances because ' 'number of model variations is too low! < %i' % thresh)
def calc_sample_covariance(buffer, lij, bij, beta): """ Calculate trace covariance matrix based on given trace values. Parameters ---------- lpoints : list of list points (e.g. buffer of traces) lij : `beat.utility.ListArrayOrdering` that holds orderings of RVs beta : float tempering parameter of the trace Returns ------- cov : :class:`numpy.ndarray` weighted covariances (NumPy > 1.10. required) """ n_points = len(buffer) population_array = num.zeros((n_points, bij.ordering.size)) for i, (lpoint, _) in enumerate(buffer): point = lij.l2d(lpoint) population_array[i, :] = bij.map(point) like_idx = lij.ordering['like'].list_ind weights = num.array([lpoint[like_idx] for lpoint, _ in buffer]) temp_weights = num.exp((weights - weights.max())).ravel() norm_weights = temp_weights / num.sum(temp_weights) cov = num.cov( population_array, aweights=norm_weights, bias=False, rowvar=0) cov = ensure_cov_psd(cov) if num.isnan(cov).any() or num.isinf(cov).any(): logger.warn( 'Proposal covariances contain Inf or NaN! ' 'For chain with beta: %f ' 'Buffer size maybe too small! Keeping previous proposal.' % beta) cov = None return cov
def calc_covariance(self): """ Calculate trace covariance matrix based on importance weights. Returns ------- cov : :class:`numpy.ndarray` weighted covariances (NumPy > 1.10. required) """ cov = np.cov(self.array_population, aweights=self.weights.ravel(), bias=False, rowvar=0) cov = utility.ensure_cov_psd(cov) if np.isnan(cov).any() or np.isinf(cov).any(): raise ValueError('Sample covariances contains Inf or NaN!') return cov
def calc_covariance(self): """ Calculate trace covariance matrix based on importance weights. Returns ------- cov : :class:`numpy.ndarray` weighted covariances (NumPy > 1.10. required) """ cov = np.cov( self.array_population, aweights=self.weights.ravel(), bias=False, rowvar=0) cov = utility.ensure_cov_psd(cov) if np.isnan(cov).any() or np.isinf(cov).any(): raise ValueError( 'Found "NaN" or "Inf" in proposal covariance! ' 'Correct model definition?') return cov
def update_weights(self, point, n_jobs=1, plot=False, chop_bounds=['b', 'c']): """ Updates weighting matrixes (in place) with respect to the point in the solution space. Parameters ---------- point : dict with numpy array-like items and variable name keys """ if not self.weights: self.init_weights() sc = self.config self.point2sources(point) # update data covariances in case model dependend non-toeplitz if self.config.noise_estimator.structure == 'non-toeplitz': logger.info('Updating data-covariances ...') self.analyse_noise(point, chop_bounds=chop_bounds) crust_inds = range(*sc.gf_config.n_variations) thresh = 5 if len(crust_inds) > thresh: logger.info('Updating seismic velocity model-covariances ...') if self.config.noise_estimator.structure == 'non-toeplitz': logger.warning( 'Non-toeplitz estimation in combination with model ' 'prediction covariances is still EXPERIMENTAL and results' ' should be interpreted with care!!') for wmap in self.wavemaps: wc = wmap.config arrival_times = wmap._arrival_times if self.config.station_corrections: arrival_times += point[wmap.time_shifts_id][ wmap.station_correction_idxs] for channel in wmap.channels: tidxs = wmap.get_target_idxs([channel]) for station, tidx in zip(wmap.stations, tidxs): logger.debug('Channel %s of Station %s ' % (channel, station.station)) crust_targets = heart.init_seismic_targets( stations=[station], earth_model_name=sc.gf_config.earth_model_name, channels=channel, sample_rate=sc.gf_config.sample_rate, crust_inds=crust_inds, reference_location=sc.gf_config.reference_location) t0 = time() cov_pv = cov.seismic_cov_velocity_models( engine=self.engine, sources=self.sources, targets=crust_targets, wavename=wmap.name, arrival_taper=wc.arrival_taper, arrival_time=arrival_times[tidx], filterer=wc.filterer, chop_bounds=chop_bounds, plot=plot, n_jobs=n_jobs) t1 = time() logger.debug('%s: Calculate weight time %f' % (station.station, (t1 - t0))) cov_pv = utility.ensure_cov_psd(cov_pv) self.engine.close_cashed_stores() dataset = wmap.datasets[tidx] dataset.covariance.pred_v = cov_pv else: logger.info( 'Not updating seismic velocity model-covariances because ' 'number of model variations is too low! < %i' % thresh) for wmap in self.wavemaps: logger.info('Updating weights of wavemap %s' % wmap._mapid) for i, dataset in enumerate(wmap.datasets): choli = dataset.covariance.chol_inverse # update shared variables dataset.covariance.update_slog_pdet() wmap.weights[i].set_value(choli)
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)