base.py 2.45 KB
Newer Older
Sebastian Heimann's avatar
Sebastian Heimann committed
1
2
import copy
import numpy as num
Marius Isken's avatar
Marius Isken committed
3
from pyrocko import util
Sebastian Heimann's avatar
Sebastian Heimann committed
4
from pyrocko.guts import Object, Int
Marius Isken's avatar
Marius Isken committed
5

Sebastian Heimann's avatar
Sebastian Heimann committed
6
7
8
9
from ..targets import TargetAnalysisResult
from ..meta import Forbidden


Sebastian Heimann's avatar
Sebastian Heimann committed
10
11
12
guts_prefix = 'grond'


Sebastian Heimann's avatar
Sebastian Heimann committed
13
14
15
16
class Analyser(object):

    def __init__(self, niter):
        self.niter = niter
Marius Isken's avatar
Marius Isken committed
17
        self.pbar = util.progressbar('analysing problem', niter)
Sebastian Heimann's avatar
Sebastian Heimann committed
18

Marius Isken's avatar
Marius Isken committed
19
    def analyse(self, problem):
Sebastian Heimann's avatar
Sebastian Heimann committed
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
        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 = num.array(wproblem.get_parameter_bounds(), dtype=num.float)
        npar = xbounds.shape[0]

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

        isbad_mask = None
Marius Isken's avatar
Marius Isken committed
43
44

        self.pbar.start()
Marius Isken's avatar
Marius Isken committed
45
        for iiter in range(self.niter):
Marius Isken's avatar
Marius Isken committed
46
            self.pbar.update(iiter)
Sebastian Heimann's avatar
Sebastian Heimann committed
47
48
            while True:
                x = []
Marius Isken's avatar
Marius Isken committed
49
                for ipar in range(npar):
Sebastian Heimann's avatar
Sebastian Heimann committed
50
51
52
53
54
55
56
57
58
59
60
61
62
63
                    v = rstate.uniform(xbounds[ipar, 0], xbounds[ipar, 1])
                    x.append(v)

                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
64
            ms = wproblem.evaluate(x, mask=isok_mask)[:, 1]
Sebastian Heimann's avatar
Sebastian Heimann committed
65
66
67
            mss[iiter, :] = ms

            isbad_mask = num.isnan(ms)
Marius Isken's avatar
Marius Isken committed
68
        self.pbar.finish()
Sebastian Heimann's avatar
Sebastian Heimann committed
69
70
71
72
73

        mean_ms = num.mean(mss, axis=0)
        weights = 1. / mean_ms
        groups, ngroups = wproblem.get_group_mask()

Marius Isken's avatar
Marius Isken committed
74
        for igroup in range(ngroups):
Sebastian Heimann's avatar
Sebastian Heimann committed
75
76
77
78
79
80
81
82
83
84
            weights[groups == igroup] /= (
                num.nansum(weights[groups == igroup]) /
                num.nansum(num.isfinite(weights[groups == igroup])))

        for weight, target in zip(weights, problem.waveform_targets):
            target.analysis_result = TargetAnalysisResult(
                balancing_weight=float(weight))


class AnalyserConfig(Object):
85
    niterations = Int.T(default=1000)
Sebastian Heimann's avatar
Sebastian Heimann committed
86
87

    def get_analyser(self):
88
        return Analyser(niter=self.niterations)
Sebastian Heimann's avatar
Sebastian Heimann committed
89
90
91
92
93
94


__all__ = '''
    Analyser
    AnalyserConfig
'''.split()