Пример #1
0
def read_info(path):
    try:
        info = guts.load(filename=path)
    except OSError:
        raise GrondError('Cannot read Grond run info file: %s' % path)

    if not isinstance(info, RunInfo):
        raise GrondError('Invalid Grond run info in file "%s".' % path)

    return info
Пример #2
0
def read_config(path):
    try:
        config = guts.load(filename=path)
    except OSError:
        raise GrondError(
            'cannot read Grond clustering configuration file: %s' % path)

    if not isinstance(config, Clustering):
        raise GrondError(
            'invalid Grond clustering configuration in file "%s"' % path)

    return config
Пример #3
0
def read_config(path):
    try:
        config = guts.load(filename=path)
    except OSError:
        raise GrondError('cannot read Grond report configuration file: %s' %
                         path)

    if not isinstance(config, ReportConfig):
        raise GrondError('invalid Grond report configuration in file "%s"' %
                         path)

    config.set_basepath(op.dirname(path) or '.')
    return config
Пример #4
0
def load_misfit_result_collection(path):
    try:
        obj = load(filename=path)

    except OSError as e:
        raise GrondError(
            'Failed to read ensemble misfit results from file "%s" (%s)' %
            (path, e))

    if not isinstance(obj, MisfitResultCollection):
        raise GrondError(
            'File "%s" does not contain any misfit result collection.' % path)

    return obj
Пример #5
0
def read_config(path):
    get_all_plot_classes()  # make sure all plot modules are imported
    try:
        config = guts.load(filename=path)
    except OSError:
        raise GrondError('Cannot read Grond report configuration file: %s' %
                         path)

    if not isinstance(config, ReportConfig):
        raise GrondError('Invalid Grond report configuration in file "%s".' %
                         path)

    config.set_basepath(op.dirname(path) or '.')
    return config
Пример #6
0
    def load(cls, path):
        collection = load(filename=path)
        if not isinstance(collection, PlotConfigCollection):
            raise GrondError(
                'invalid plot collection configuration in file "%s"' % path)

        return collection
Пример #7
0
def write_info(info, path):
    try:
        guts.dump(info,
                  filename=path,
                  header='Grond run info file, version %s' % __version__)

    except OSError:
        raise GrondError('Cannot write Grond run info file: %s' % path)
Пример #8
0
    def load(cls, path):
        from grond.plot import get_all_plot_classes
        get_all_plot_classes()  # make sure all plot classes are loaded
        collection = load(filename=path)
        if not isinstance(collection, PlotConfigCollection):
            raise GrondError(
                'invalid plot collection configuration in file "%s"' % path)

        return collection
Пример #9
0
    def random_uniform(self, xbounds, rstate, fixed_magnitude=None):
        if fixed_magnitude is not None:
            raise GrondError(
                'Setting fixed magnitude in random model generation not '
                'supported for this type of problem.')

        x = rstate.uniform(0., 1., self.nparameters)
        x *= (xbounds[:, 1] - xbounds[:, 0])
        x += xbounds[:, 0]
        return x
Пример #10
0
def write_config(config, path):
    try:
        guts.dump(config,
                  filename=path,
                  header='Grond clustering configuration file, version %s' %
                  __version__)

    except OSError:
        raise GrondError('cannot write Grond report configuration file: %s' %
                         path)
Пример #11
0
    def random_uniform(self, xbounds, rstate, fixed_magnitude=None):
        if fixed_magnitude is not None:
            raise GrondError(
                'Setting fixed magnitude in random model generation not '
                'supported for this type of problem.')

        x = num.zeros(self.nparameters)
        for i in range(self.nparameters):
            x[i] = rstate.uniform(xbounds[i, 0], xbounds[i, 1])

        return x
Пример #12
0
    def get_random_model(self, ntries_limit=100):
        xbounds = self.get_parameter_bounds()

        for _ in range(ntries_limit):
            x = self.random_uniform(xbounds, rstate=g_rstate)
            try:
                return self.preconstrain(x)

            except Forbidden:
                pass

        raise GrondError(
            'Could not find any suitable candidate sample within %i tries' %
            (ntries_limit))
Пример #13
0
    def get_sample(self, problem, iiter, chains):
        assert 0 <= iiter < self.niterations

        ntries_preconstrain = 0
        for ntries_preconstrain in range(self.ntries_preconstrain_limit):
            try:
                return problem.preconstrain(
                    self.get_raw_sample(problem, iiter, chains))

            except Forbidden:
                pass

        raise GrondError(
            'could not find any suitable candidate sample within %i tries' %
            (self.ntries_preconstrain_limit))
Пример #14
0
def write_config(config, path):
    try:
        basepath = config.get_basepath()
        dirname = op.dirname(path) or '.'
        config.change_basepath(dirname)
        guts.dump(config,
                  filename=path,
                  header='Grond report configuration file, version %s' %
                  __version__)

        config.change_basepath(basepath)

    except OSError:
        raise GrondError('cannot write Grond report configuration file: %s' %
                         path)
Пример #15
0
    def analyse(self, problem, ds):
        if self.niter == 0:
            return

        wtargets = []
        if not problem.has_waveforms:
            return

        for target in problem.waveform_targets:
            wtarget = copy.copy(target)
            wtarget.flip_norm = True
            wtarget.weight = 1.0
            wtargets.append(wtarget)

        wproblem = problem.copy()
        wproblem.targets = wtargets

        xbounds = wproblem.get_parameter_bounds()

        misfits = num.zeros((self.niter, wproblem.ntargets, 2))
        rstate = num.random.RandomState(123)

        isbad_mask = None

        self._tlog_last = 0
        for iiter in range(self.niter):
            self.log_progress(problem, iiter, self.niter)
            while True:
                if self.use_reference_magnitude:
                    try:
                        fixed_magnitude = wproblem.base_source.get_magnitude()
                    except gf.DerivedMagnitudeError:
                        raise GrondError(
                            'Cannot use use_reference_magnitude for this type '
                            'of source model.')
                else:
                    fixed_magnitude = None

                x = wproblem.random_uniform(xbounds,
                                            rstate,
                                            fixed_magnitude=fixed_magnitude)

                try:
                    x = wproblem.preconstrain(x)
                    break

                except Forbidden:
                    pass

            if isbad_mask is not None and num.any(isbad_mask):
                isok_mask = num.logical_not(isbad_mask)
            else:
                isok_mask = None
            misfits[iiter, :, :] = wproblem.misfits(x, mask=isok_mask)

            isbad_mask = num.isnan(misfits[iiter, :, 1])

        mean_ms = num.mean(misfits[:, :, 0], axis=0)

        mean_ps = num.mean(misfits[:, :, 1], axis=0)

        weights = 1. / mean_ps
        families, nfamilies = wproblem.get_family_mask()

        for ifamily in range(nfamilies):
            weights[families == ifamily] /= (
                num.nansum(weights[families == ifamily]) /
                num.nansum(num.isfinite(weights[families == ifamily])))

        if self.cutoff is not None:
            weights[mean_ms / mean_ps > self.cutoff] = 0.0

        for weight, target in zip(weights, problem.waveform_targets):
            target.analyser_results['target_balancing'] = \
                TargetBalancingAnalyserResult(weight=float(weight))

        for itarget, target in enumerate(problem.waveform_targets):
            logger.info(
                ('Balancing analysis for target "%s":\n'
                 '  m/p: %g\n'
                 '  weight: %g\n') % (target.string_id(), mean_ms[itarget] /
                                      mean_ps[itarget], weights[itarget]))
Пример #16
0
 def raise_invalid_norm_exponent(self):
     raise GrondError('Invalid norm exponent: %f' % self.norm_exponent)
Пример #17
0
 def get_gf_store(self, target):
     if self.get_engine() is None:
         raise GrondError('Cannot get GF Store, modelling is not set up!')
     return self.get_engine().get_store(target.store_id)
Пример #18
0
    def combine_misfits(self,
                        misfits,
                        extra_weights=None,
                        extra_residuals=None,
                        extra_correlated_weights=dict(),
                        get_contributions=False):
        '''
        Combine misfit contributions (residuals) to global or bootstrap misfits

        :param misfits: 3D array ``misfits[imodel, iresidual, 0]`` are the
            misfit contributions (residuals) ``misfits[imodel, iresidual, 1]``
            are the normalisation contributions. It is also possible to give
            the misfit and normalisation contributions for a single model as
            ``misfits[iresidual, 0]`` and misfits[iresidual, 1]`` in which
            case, the first dimension (imodel) of the result will be stipped
            off.

        :param extra_weights: if given, 2D array of extra weights to be applied
            to the contributions, indexed as
            ``extra_weights[ibootstrap, iresidual]``.

        :param extra_residuals: if given, 2D array of perturbations to be added
            to the residuals, indexed as
            ``extra_residuals[ibootstrap, iresidual]``.

        :param extra_correlated_weights: if a dictionary of
            ``imisfit: correlated weight matrix`` is passed a correlated
            weight matrix is applied to the misfit and normalisation values.
            `imisfit` is the starting index in the misfits vector the
            correlated weight matrix applies to.

        :param get_contributions: get the weighted and perturbed contributions
            (don't do the sum).

        :returns: if no *extra_weights* or *extra_residuals* are given, a 1D
            array indexed as ``misfits[imodel]`` containing the global misfit
            for each model is returned, otherwise a 2D array
            ``misfits[imodel, ibootstrap]`` with the misfit for every model and
            weighting/residual set is returned.
        '''
        if misfits.ndim == 2:
            misfits = misfits[num.newaxis, :, :]
            return self.combine_misfits(misfits, extra_weights,
                                        extra_residuals,
                                        extra_correlated_weights,
                                        get_contributions)[0, ...]

        if extra_weights is None and extra_residuals is None:
            return self.combine_misfits(misfits, False, False,
                                        extra_correlated_weights,
                                        get_contributions)[:, 0]

        assert misfits.ndim == 3
        assert not num.any(extra_weights) or extra_weights.ndim == 2
        assert not num.any(extra_residuals) or extra_residuals.ndim == 2

        if self.norm_exponent != 2 and extra_correlated_weights:
            raise GrondError('Correlated weights can only be used '
                             ' with norm_exponent=2')

        exp, root = self.get_norm_functions()

        nmodels = misfits.shape[0]
        nmisfits = misfits.shape[1]  # noqa

        mf = misfits[:, num.newaxis, :, :].copy()

        if num.any(extra_residuals):
            mf = mf + extra_residuals[num.newaxis, :, :, num.newaxis]

        res = mf[..., 0]
        norms = mf[..., 1]

        for imisfit, corr_weight_mat in extra_correlated_weights.items():

            jmisfit = imisfit + corr_weight_mat.shape[0]

            for imodel in range(nmodels):
                corr_res = res[imodel, :, imisfit:jmisfit]
                corr_norms = norms[imodel, :, imisfit:jmisfit]

                res[imodel, :, imisfit:jmisfit] = \
                    correlated_weights(corr_res, corr_weight_mat)

                norms[imodel, :, imisfit:jmisfit] = \
                    correlated_weights(corr_norms, corr_weight_mat)

        # Apply normalization family weights (these weights depend on
        # on just calculated correlated norms!)
        weights_fam = \
            self.inter_family_weights2(norms[:, 0, :])[:, num.newaxis, :]

        weights_fam = exp(weights_fam)

        res = exp(res)
        norms = exp(norms)

        res *= weights_fam
        norms *= weights_fam

        weights_tar = self.get_target_weights()[num.newaxis, num.newaxis, :]
        if num.any(extra_weights):
            weights_tar = weights_tar * extra_weights[num.newaxis, :, :]

        weights_tar = exp(weights_tar)

        res = res * weights_tar
        norms = norms * weights_tar

        if get_contributions:
            return res / num.nansum(norms, axis=2)[:, :, num.newaxis]

        result = root(num.nansum(res, axis=2) / num.nansum(norms, axis=2))

        assert result[result < 0].size == 0
        return result
Пример #19
0
    def post_process(self, engine, source, tr_syn):

        tr_syn = tr_syn.pyrocko_trace()
        nslc = self.codes

        config = self.misfit_config

        tmin_fit, tmax_fit, tfade, tfade_taper = \
            self.get_taper_params(engine, source)

        ds = self.get_dataset()

        tobs, tsyn = self.get_pick_shift(engine, source)
        if None not in (tobs, tsyn):
            tobs_shift = tobs - tsyn
        else:
            tobs_shift = 0.0

        tr_syn.extend(tmin_fit - tfade * 2.0,
                      tmax_fit + tfade * 2.0,
                      fillmethod='repeat')

        freqlimits = self.get_freqlimits()

        if config.quantity == 'displacement':
            syn_resp = None
        elif config.quantity == 'velocity':
            syn_resp = trace.DifferentiationResponse(1)
        elif config.quantity == 'acceleration':
            syn_resp = trace.DifferentiationResponse(2)
        else:
            GrondError('Unsupported quantity: %s' % config.quantity)

        tr_syn = tr_syn.transfer(freqlimits=freqlimits,
                                 tfade=tfade,
                                 transfer_function=syn_resp)

        tr_syn.chop(tmin_fit - 2 * tfade, tmax_fit + 2 * tfade)

        tmin_obs, tmax_obs = self.get_cutout_timespan(tmin_fit + tobs_shift,
                                                      tmax_fit + tobs_shift,
                                                      tfade)

        try:
            tr_obs = ds.get_waveform(
                nslc,
                quantity=config.quantity,
                tinc_cache=1.0 / (config.fmin or 0.1 * config.fmax),
                tmin=tmin_fit + tobs_shift - tfade,
                tmax=tmax_fit + tobs_shift + tfade,
                tfade=tfade,
                freqlimits=freqlimits,
                deltat=tr_syn.deltat,
                cache=True,
                backazimuth=self.get_backazimuth_for_waveform())

            if tobs_shift != 0.0:
                tr_obs = tr_obs.copy()
                tr_obs.shift(-tobs_shift)

            mr = misfit(tr_obs,
                        tr_syn,
                        taper=trace.CosTaper(tmin_fit - tfade_taper, tmin_fit,
                                             tmax_fit, tmax_fit + tfade_taper),
                        domain=config.domain,
                        exponent=config.norm_exponent,
                        flip=self.flip_norm,
                        result_mode=self._result_mode,
                        tautoshift_max=config.tautoshift_max,
                        autoshift_penalty_max=config.autoshift_penalty_max,
                        subtargets=self._piggyback_subtargets)

            self._piggyback_subtargets = []

            mr.tobs_shift = float(tobs_shift)
            mr.tsyn_pick = float_or_none(tsyn)

            return mr

        except NotFound as e:
            logger.debug(str(e))
            raise gf.SeismosizerError('No waveform data: %s' % str(e))